Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Document HTTP statuses that API routes raise but never declared - #71011

Merged
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses
Aug 14, 2026
Merged

Document HTTP statuses that API routes raise but never declared#71011
pierrejeambrun merged 1 commit into
apache:mainfrom
ColtenOuO:api-document-raised-http-statuses

Conversation

@ColtenOuO

@ColtenOuOColtenOuO commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #67570, #67571 and #70992, which each fixed one instance of the same
drift: a handler raises an HTTP status that create_openapi_http_exception_doc(...)
never declares, so the generated spec — and every client built from it — has no model
for a response the API really returns.

EndpointUndeclaredReached when
POST /backfills/dry_run400the Dag's allowed_run_types excludes backfill
DELETE /dags/{dag_id}/dagRuns/{dag_run_id}409the run's state is not in DagRunMutableStates
GET /dags/{dag_id}/dagRuns400a partition_date filter with dag_id=~, or against a non-partitioned Dag
DELETE /dags/{dag_id}409task instances are still running
PATCH /hitlDetails/{dag_id}/{dag_run_id}/{task_id}400chosen_options outside options, or several sent to a non-multiple detail
POST /dags/{dag_id}/clearTaskInstances400past/future with a run that has no logical date
GET /ui/dags/{dag_id}/latest_run400dag_id=~
GET /ui/dependencies400dependency_type=data with a missing or non-numeric asset: node id

Each is driven by request input or by persisted state, so each is really returned today.

ui/dependencies.py also had one bare raise HTTPException(404, ...); it now uses
status.HTTP_404_NOT_FOUND, the same tidy-up as #67571.

xcom.py is deliberately left out — it is fixed in #70992.

Behaviour

Otherwise unchanged: only responses= declarations, so the regenerated spec and UI
client are additive (6 additions to the public spec, 2 to _private_ui.yaml, no
deletions). No new tests — the statuses were already produced and are already covered.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5)

@bbovenzi

Copy link
Copy Markdown
Contributor

What does 404 on a POST variable endpoint mean?

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from a92144a to dbdebe5CompareAugust 5, 2026 07:39
@ColtenOuO

ColtenOuO commented Aug 5, 2026

Copy link
Copy Markdown
ContributorAuthor

Sorry about that.

It doesn't mean anything on a create endpoint.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted. What I didn't check was whether each raise can actually fire, and this one can't.

I've removed the branch. If the read-back ever did come back empty, response validation now gives a 500, which is the right answer for a write that silently didn't happen.

The description is updated too: that row is gone, and the table now says when each of the remaining statuses is returned.

Thanks for your review!

@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from dbdebe5 to 6b419f7CompareAugust 5, 2026 11:33

@jason810496jason810496 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for adding the missing status code.

I found these with a script that compares the statuses each handler raises against the ones its create_openapi_http_exception_doc(...) declares, so the list is everything that had drifted.

I prefer to introduce the script you mentioned as pre-commit (prek) hook static check (please take the dev/script as referece) that ensure all the status code that might raise within the route are documented in the router definition level to prevent the further drift from happening again instead of one-time manual fix.

Which means we might need to walk into the module level (e.g. the exception might be raise within the common function that we imported at router level).

Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
Comment threadairflow-core/src/airflow/api_fastapi/core_api/routes/public/variables.py Outdated
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 6b419f7 to 53959b0CompareAugust 6, 2026 14:34
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

Thanks again!

Reverted the post_variable change.

This PR now only adds responses= declarations and doesn't touch any route implementation.

Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
@ColtenOuO
ColtenOuOforce-pushed the api-document-raised-http-statuses branch from 53959b0 to 4b34d9dCompareAugust 13, 2026 11:06
@ColtenOuO

Copy link
Copy Markdown
ContributorAuthor

rebase to lastest upstream/main and re-run the CI.

@pierrejeambrunpierrejeambrun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, LGTM.

@pierrejeambrunpierrejeambrun added the backport-to-v3-3-test Backport to v3-3-test label Aug 14, 2026
@pierrejeambrunpierrejeambrun added this to the Airflow 3.3.2 milestone Aug 14, 2026
@pierrejeambrun
pierrejeambrun merged commit 7c0b3e6 into apache:mainAug 14, 2026
156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport successfully created: v3-3-test

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

StatusBranchResult
v3-3-testPR Link

pierrejeambrun pushed a commit that referenced this pull request Aug 17, 2026
…clared (#71011) (#71622)
Handlers raise statuses that create_openapi_http_exception_doc never declares, so
the generated spec — and every client built from it — has no model for a response
the API really returns.
(cherry picked from commit 7c0b3e6)
Co-authored-by: Jyun-An Chen <jun930436@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:UIRelated to UI/UX. For Frontend Developers.backport-to-v3-3-testBackport to v3-3-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@ColtenOuO@bbovenzi@pierrejeambrun@jason810496