Skip to content

fix(extensions): reject malformed progress receipts - #3104

Open
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/extension-progress-document-shape
Open

fix(extensions): reject malformed progress receipts#3104
tang-vu wants to merge 1 commit into
Osmantic:mainfrom
tang-vu:fix/extension-progress-document-shape

Conversation

@tang-vu

@tang-vu tang-vu commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • centralize loading of extension progress receipts and accept only JSON objects
  • return the documented idle receipt when the host-agent file contains any other valid JSON shape
  • rebuild an object-shaped error receipt when a failed mutation encounters malformed progress state

Why this matters

The dashboard API reads progress receipts written across the host-agent boundary. A truncated writer is already handled as invalid JSON, but valid JSON such as null, an array, or a scalar currently either crashes object consumers with .get/item-assignment errors or leaks a scalar from the public progress endpoint. That can turn an install failure into a second 500 and leaves the UI without its stable {service_id, status} contract.

Behavioral invariant

An extension progress receipt is usable only when its JSON root is an object. Every other root shape is treated as absent, and recording a terminal error repairs the receipt to an object.

Overlap check

Searched open and closed upstream PRs for extension progress receipts, malformed JSON/document shapes, and the changed production/test files. #3065 changes frontend polling concurrency only; merged #1056 covers catalog timeouts and merged #1724 covers model actions. None validates the backend receipt root or repairs a malformed receipt, so this scope is independent.

Validation

  • pytest -q tests/test_extensions.py -k 'non_object_progress or non_object_receipts or progress_endpoint_during_install or sets_error_status' ? 12 passed
  • pytest -q tests/test_extensions.py ? 265 passed, 5 skipped
  • python -m compileall -q routers/extensions.py tests/test_extensions.py
  • git diff --check

Tradeoffs and rollback

Malformed receipts are deliberately treated like missing state rather than surfaced as an API error, matching the existing invalid-JSON behavior. Files are not deleted, preserving host diagnostics. Reverting this commit restores the prior permissive JSON-root behavior.

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