Skip to content

Prevent scheduler crash when process/thread missing from log format#69402

Open
anxkhn wants to merge 1 commit into
apache:mainfrom
anxkhn:fix/log-formatter-missing-process-thread
Open

Prevent scheduler crash when process/thread missing from log format#69402
anxkhn wants to merge 1 commit into
apache:mainfrom
anxkhn:fix/log-formatter-missing-process-thread

Conversation

@anxkhn

@anxkhn anxkhn commented Jul 5, 2026

Copy link
Copy Markdown

When a log record reaches the percent formatter without callsite information, for
example a standard-library warning routed through Airflow's logging bridge, the
process and thread fields are absent. The formatter fell back to the
"(unknown)" string for every missing callsite field, so a log format using
the numeric %(process)d or %(thread)d specifiers (the default console
format renders a process-id column) raised
TypeError: %d format: a real number is required, not str and could take down
the scheduler at startup.

This gives those two numeric callsite parameters a numeric fallback of 0, the
same way lineno is already handled a few lines above, so the format string
never receives a string where a number is expected. The "(unknown)" string
fallback is left intact for the text callsite parameters
(pathname/module/threadName/processName), which are rendered with
%s.

A parametrized regression test formats %(process)d:%(thread)d for a record
with no callsite info (the exact issue reproduction) and for one where those keys
are explicitly None, asserting it renders 0:0 instead of raising; it fails
with the TypeError before the change and passes after.

closes: #66195


Was generative AI tooling used to co-author this PR?
  • Yes

Final diff (2 files, +24/-0)

  1. shared/logging/src/airflow_shared/logging/percent_formatter.py (+6): in
    _LazyLogRecordDict.__getitem__, add
    if key == "process" or key == "thread": return self.event.get(key) or 0
    immediately after the existing lineno numeric-fallback case, with a short
    comment explaining why (numeric %d params must not fall back to the
    "(unknown)" string used for text params).
  2. shared/logging/tests/logging/test_percent_formatter.py (+18): add
    test_numeric_callsite_without_process_or_thread, parametrized missing
    (no callsite keys, the issue repro) and none (keys present but None), in
    the existing TestPercentFormatRender class next to test_no_callsite; adds
    the import pytest it needs.

When a record reaches the percent formatter without callsite information,
for example a stdlib warning routed through the logging bridge, the process
and thread fields are absent. The formatter fell back to the "(unknown)"
string for them, so a format string using the numeric "%(process)d" or
"%(thread)d" specifiers raised "TypeError: %d format: a real number is
required" and could take down the scheduler at startup.

Give those two numeric callsite parameters a numeric fallback of 0, the same
way lineno is already handled, so the format never receives a string where a
number is expected.
@potiuk

potiuk commented Jul 5, 2026

Copy link
Copy Markdown
Member

Nice!

@potiuk potiuk added this to the Airflow 3.3.1 milestone Jul 5, 2026
@potiuk potiuk added the backport-to-v3-3-test Backport to v3-3-test label Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Warning error formatting crashes the scheduler

2 participants