{"record":{"id":"1318ad33a5e3cb4e","repo":"666ghj/MiroFish","slug":"workspace-does-not-exist","errorCode":null,"errorMessage":"workspace does not exist","messagePattern":"workspace does not exist","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":458,"sourceCode":"    if first_snapshot is not None:\n        if first_snapshot < generated_at:\n            raise StarHistoryError(\"first snapshot cannot predate reconstruction\")\n        if previous_day is not None and previous_day >= first_snapshot.date():\n            raise StarHistoryError(\"reconstruction dates must predate snapshots\")\n\n\ndef canonical_state_bytes(state: Mapping[str, Any]) -> bytes:\n    validate_state(state)\n    return (\n        json.dumps(state, ensure_ascii=False, indent=2, sort_keys=True) + \"\\n\"\n    ).encode(\"utf-8\")\n\n\ndef _safe_workspace(workspace: Path) -> Path:\n    try:\n        root = workspace.resolve(strict=True)\n    except OSError as exc:\n        raise StarHistoryError(\"workspace does not exist\") from exc\n    if not root.is_dir():\n        raise StarHistoryError(\"workspace is not a directory\")\n    return root\n\n\ndef _safe_target(workspace: Path, relative: Path, create_parent: bool) -> Path:\n    root = _safe_workspace(workspace)\n    if relative.is_absolute() or \"..\" in relative.parts:\n        raise StarHistoryError(\"output path escaped the workspace\")\n\n    current = root\n    for part in relative.parts[:-1]:\n        current = current / part\n        if current.is_symlink():\n            raise StarHistoryError(\"output directory cannot be a symbolic link\")\n    target = root / relative\n    if target.is_symlink():\n        raise StarHistoryError(\"output file cannot be a symbolic link\")","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L440-L476","documentation":"Raised by _safe_workspace() (used by _safe_target) when Path.resolve(strict=True) raises OSError for the workspace path — the workspace directory cannot be resolved because it (or a component of it) does not exist or is inaccessible. This is an environment/configuration guard that runs before any output file is written.","triggerScenarios":"Calling any code path that reaches _safe_target (e.g. writing state/output files) with a workspace Path pointing to a missing directory, a path with a nonexistent parent component, or one with permission-denied components.","commonSituations":"Configuring an output workspace that was never created; a CI job where the workspace dir is created in a later step; typos in the configured workspace path; the directory being cleaned up between runs.","solutions":["Verify the workspace path exists and is spelled correctly","Create the workspace directory (mkdir -p) before running the script","Check the script's workspace/output configuration option for the correct value","If permissions are the issue, fix ownership/ACLs on the path components"],"exampleFix":"# before\nworkspace = Path(\"/srv/star-history-out\")  # does not exist\n# after\nworkspace = Path(\"/srv/star-history-out\")\nworkspace.mkdir(parents=True, exist_ok=True)","handlingStrategy":"validation","validationCode":"workspace = Path(config[\"workspace\"])\nif not workspace.exists():\n    raise FileNotFoundError(f\"workspace missing: {workspace}\")","typeGuard":"from pathlib import Path\n\ndef workspace_exists(workspace: Path) -> bool:\n    return workspace.exists()","tryCatchPattern":"try:\n    write_output(workspace, relative, data)\nexcept StarHistoryError as exc:\n    if \"workspace does not exist\" in str(exc):\n        workspace.mkdir(parents=True, exist_ok=True)\n        write_output(workspace, relative, data)\n","preventionTips":["Create the workspace directory in setup before running the script","Add a preflight check for configured paths at startup","Use absolute workspace paths in config to avoid cwd-relative surprises"],"tags":["filesystem","configuration","environment"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}