666ghj/MiroFish · error · StarHistoryError
Star count file is not a regular file
Error message
Star count file is not a regular file
What it means
After a successful O_NOFOLLOW open, load_star_count_file fstats the descriptor and requires a regular file (stat.S_ISREG). FIFOs, sockets, character/block devices, and directories are rejected so the reader never blocks on a fifo or trust device semantics for a tiny decimal count.
Source
Thrown at scripts/star_history.py:523
if len(payload) > limit:
raise StarHistoryError(f"{label} exceeded the size limit")
return payload
def load_star_count_file(path: Path) -> int:
"""Read a tiny, symlink-safe decimal count produced by the fetch-only step."""
flags = os.O_RDONLY
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
try:
descriptor = os.open(path, flags)
except OSError as exc:
raise StarHistoryError("Star count file is missing or unsafe") from exc
try:
metadata = os.fstat(descriptor)
if not stat.S_ISREG(metadata.st_mode):
raise StarHistoryError("Star count file is not a regular file")
payload = os.read(descriptor, MAX_COUNT_FILE_BYTES + 1)
except OSError as exc:
raise StarHistoryError("could not read Star count file") from exc
finally:
os.close(descriptor)
if len(payload) > MAX_COUNT_FILE_BYTES:
raise StarHistoryError("Star count file exceeded the size limit")
if not re.fullmatch(rb"(?:0|[1-9][0-9]*)\n?", payload):
raise StarHistoryError("Star count file must contain one decimal integer")
count = int(payload)
if count > MAX_STAR_COUNT:
raise StarHistoryError("Star count exceeded the supported range")
return count
def load_state(workspace: Path, require_canonical: bool = True) -> dict[str, Any]:
state_path = _safe_target(workspace, STATE_RELATIVE, create_parent=False)View on GitHub (pinned to b5b53acc57)
Solutions
- stat the path: it should be '-rw-' not 'p','s','c','b', or 'd'
- Remove the non-regular file: rm / path-to-object
- Re-run the fetch step to write a plain regular file
- If this appears in tests, assert the fixture creates a file, not a directory
Example fix
# before
os.mkfifo(count_path) # test fixture mistake
# after
count_path.write_text('1234\n') # regular file Defensive patterns
Strategy: type-guard
Validate before calling
import stat, os
st = os.lstat(p)
if not stat.S_ISREG(st.st_mode):
raise RuntimeError(f'count path is not a regular file: mode {oct(st.st_mode)}') Type guard
def is_regular_file(p: Path) -> bool:
try:
return stat.S_ISREG(os.lstat(p).st_mode)
except OSError:
return False Prevention
- Fixtures must create files, not fifos/dirs
- rm stray fifos at artifact paths
- Use lstat (not stat) so symlinks are caught as non-regular too
- Keep artifact directories owned by the pipeline only
When it happens
Trigger: The path handed to load_star_count_file is a named pipe (mkfifo), a unix socket, /dev-style device node, or a directory. Note O_NOFOLLOW only guards the final symlink hop, so other non-regular types reach this check.
Common situations: A stale fifo left by earlier tooling at the count path, tests using tmp_path fixtures that create directories where a file is expected, or deliberately crafted inputs in security review.
Related errors
- 模拟不存在: {simulation_id}
- output directory cannot be a symbolic link
- output file cannot be a symbolic link
- could not create output directory
- could not read {label}
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/62164b130772b7ae.
Report an issue: GitHub.