iflytek/astron-agent · error · GateError
Docker Compose config did not return valid JSON
Error message
Docker Compose config did not return valid JSON
What it means
_render_compose runs the selected Compose command with 'config --format json' and parses stdout with json.loads. If the output is not valid JSON (JSONDecodeError or TypeError, e.g. non-string stdout), it wraps the failure in GateError('Docker Compose config did not return valid JSON'). This guards against Compose implementations that ignore the --format json flag and emit YAML or human-readable text.
Solutions
- Upgrade to Docker Compose v2 so 'config --format json' emits pure JSON on stdout.
- Run the command manually and inspect stdout for non-JSON prefixes (warnings, banners) and remove their source.
- Check for shell aliases/wrappers around docker compose in the execution environment (unalias, use absolute path).
- Capture stdout separately from stderr (2>/dev/null) when testing to confirm which stream carries the noise.
Example fix
// diagnostic before fix docker compose config --format json | head -c 200 # shows YAML or warning text // after upgrade docker compose version # v2.x docker compose config --format json | python -m json.tool > /dev/null # ok
Defensive patterns
Strategy: validation
Validate before calling
import json, subprocess out = subprocess.run(["docker","compose","-f",f,"config","--format","json"], capture_output=True, text=True).stdout json.loads(out) # raises early if not JSON
Type guard
def is_json_object(s: str) -> bool:
import json
try:
return isinstance(json.loads(s), dict)
except (json.JSONDecodeError, TypeError):
return False Try / catch
try:
cfg = render_compose(f)
except GateError as e:
if "valid JSON" in str(e):
log(compose_raw_stdout) # inspect non-JSON noise
raise Prevention
- Avoid wrappers/aliases that prepend text to compose output.
- Upgrade to Compose v2.
- Test 'config --format json' output purity in CI.
When it happens
Trigger: The chosen compose implementation exits 0 but prints YAML/human text instead of JSON for 'config --format json' (older/v1 or aliased implementations); stdout polluted by warnings/pre-banner text; or the command output is None.
Common situations: Shell alias or wrapper intercepting docker-compose; compose v1 accepting --format but rendering text; plugin printing deprecation warnings on stdout; CI shim that logs before the command output.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- Docker Compose config returned an unexpected JSON root
- jsonData.message
- 8118
- RESPONSE_FAILED
- The lengthRange must be an array of integers
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/6c9d527507d6f62b.
Report an issue: GitHub.
Appendix: source
Thrown at docker/astronAgent/scripts/verify_security_contract.py:184
"'config --format json' is required"
)
def _render_compose(compose_file: Path) -> Mapping[str, Any]:
base_command = _select_compose_command(compose_file)
completed = subprocess.run(
list(base_command) + ["-f", compose_file.name, "config", "--format", "json"],
cwd=str(compose_file.parent),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
check=False,
)
try:
rendered = json.loads(completed.stdout)
except (json.JSONDecodeError, TypeError) as exc:
raise GateError("Docker Compose config did not return valid JSON") from exc
if not isinstance(rendered, dict):
raise GateError("Docker Compose config returned an unexpected JSON root")
return rendered
def _mapping(value: Any) -> Mapping[str, Any]:
return value if isinstance(value, dict) else {}
def _mounts(service: Mapping[str, Any], target: str) -> List[Mapping[str, Any]]:
volumes = service.get("volumes", [])
if not isinstance(volumes, list):
return []
return [
volume
for volume in volumes
if isinstance(volume, dict) and volume.get("target") == target
]View on GitHub (pinned to 5e758547a8)