Skip to content

fix: GUI returns 400 (not 403) when a POST omits the Origin header - #14

Merged
EauDoon merged 2 commits into
mainfrom
fix/gui-distinguish-missing-origin
Sep 4, 2026
Merged

fix: GUI returns 400 (not 403) when a POST omits the Origin header#14
EauDoon merged 2 commits into
mainfrom
fix/gui-distinguish-missing-origin

Conversation

@EauDoon

@EauDoon EauDoon commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Bug review of EauDoon/agent-action-stack found:

  • LOW: bin/aas-gui.mjs requestBoundaryFailure returns the same "origin" code whether the caller is missing the Origin header entirely or sent a wrong-origin header. The handler at line 100 returns 403 Forbidden for both, with the body { error: "Forbidden" }. A programmatic local client that forgets to send Origin (curl, a CI step, a non-browser agent) sees a generic 403 and has no way to tell that the only fix is to add the header. A wrong-origin POST is genuinely forbidden; a missing-Origin POST is a misconfiguration that should be 400.

Fix: add a "missing-origin" branch in requestBoundaryFailure and a 400 response with a clear "Origin header required for POST" message in the handler. Wrong-origin POSTs still get 403. Update test/gui.test.mjs to assert the 400 and the new error message.

Verified: node --test test/gui.test.mjs runs 2 tests, all pass. node --test test/stack.test.mjs still runs 40 tests, all pass.


Devin Review

…and runProve

Bug review of EauDoon/agent-action-stack found:
- MEDIUM: runAct (bin/aas.mjs) short-circuits to childProcessError when result.status !== 0, before parseStageJson is reached. Any JSON crctl wrote to stdout is dropped. The throw also bypasses failedStderr, but the bigger loss is the stdout payload: persistRunBundle only writes a stage artifact when current.raw !== undefined, and stageErrorFields never sets raw, so a `--fault duplicate` failure that surfaces as JSON on stdout is not persisted, does not appear in report.stages.act, and printHuman shows only act_code / act_reason / act_stderr. runDecide and runProve both parse the JSON first and return {ok: false, raw, status, stderr} for nonzero exits; runAct was the asymmetric outlier.

Fix: parse the JSON first, then if status is nonzero return the same {ok: false, raw, status, ...failedStderr(result)} shape that runDecide and runProve use. Throw childProcessError only when the spawn itself failed (result.error) or when the child exited nonzero with no parseable JSON.

Verified: node --test test/stack.test.mjs runs 40 tests, all pass.
Bug review of EauDoon/agent-action-stack found:
- LOW: bin/aas-gui.mjs requestBoundaryFailure returns the same "origin" code whether the caller is missing the Origin header entirely or sent a wrong-origin header. The handler at line 100 returns 403 Forbidden for both, with the body { error: "Forbidden" }. A programmatic local client that forgets to send Origin (curl, a CI step, a non-browser agent) sees a generic 403 and has no way to tell that the only fix is to add the header. A wrong-origin POST is genuinely forbidden; a missing-Origin POST is a misconfiguration that should be 400.

Fix: add a "missing-origin" branch in requestBoundaryFailure and a 400 response with a clear "Origin header required for POST" message in the handler. Wrong-origin POSTs still get 403. Update test/gui.test.mjs to assert the 400 and the new error message.

Verified: node --test test/gui.test.mjs runs 2 tests, all pass. node --test test/stack.test.mjs still runs 40 tests, all pass.
@EauDoon
EauDoon merged commit a7466d0 into main Sep 4, 2026
@EauDoon
EauDoon deleted the fix/gui-distinguish-missing-origin branch September 4, 2026 10:43

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

Comment thread bin/aas.mjs
Comment on lines +525 to +530
if (result.status !== 0) {
// A nonzero exit with parseable JSON is an unsuccessful act (the CLI
// surfaces structured errors as JSON on stdout), not a child-process
// error. Mirror runProve so persistRunBundle and printHuman see the
// structured failure and the GUI can render the stage artifact.
return { ok: false, raw: payload, status: result.status, ...failedStderr(result) };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Failed actions become successful runs

When the action child exits nonzero with JSON, runAct returns ok: false, but the orchestrator ignores it. The run records success and can exit zero.

Prompt for agents
Update bin/aas.mjs so runDemo handles a false runAct result as a failed action, preserving raw output and stderr in the stage artifact and report, setting exitCode to 1, and preventing a later successful proof from converting the overall run to success. Add stack tests using the real runAct path with a nonzero child result containing parseable JSON, and assert failed action status, nonzero run exit, preserved artifact, and appropriate proof handling.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant