#2304·open-swe

`DEFAULT_PROMPT_PATH` custom instructions are silently dropped on a non-UTF-8 locale

Author: rajarshidattapyCreated Aug 28, 2026Updated Sep 14, 2026

Severity: Medium Type: Correctness / Silent data loss File: agent/prompt.py:21-48

Description

_load_default_prompt() has two branches that read the same kind of file. One passes an explicit encoding; the other does not:

python
def _load_default_prompt() -> str:
    try:
        if DEFAULT_PROMPT_PATH:
            content = Path(DEFAULT_PROMPT_PATH).read_text().strip()          # no encoding
        else:
            content = (
                resources.files("agent.resources")
                .joinpath("default_prompt.md")
                .read_text(encoding="utf-8")                                  # encoding
                .strip()
            )
        ...
    except Exception:
        logger.warning(
            "Failed to read default prompt from %s",
            DEFAULT_PROMPT_PATH or "agent.resources/default_prompt.md",
        )
    return ""

DEFAULT_PROMPT_PATH is an operator-supplied path (os.environ.get("DEFAULT_PROMPT_PATH")).

Impact

An operator who points DEFAULT_PROMPT_PATH at a UTF-8 prompt file containing any non-ASCII character — a curly quote, an em dash, an arrow, an emoji — gets a UnicodeDecodeError on any host whose locale encoding is not UTF-8. The bare except Exception swallows it, logs a single warning, and returns "".

The result is that the agent runs with the operator's custom instructions silently missing. There is no error surfaced to the caller and no difference in agent behaviour other than the instructions being absent, which is close to the worst possible failure mode for a configuration knob: the deployment looks healthy and the agent quietly ignores its custom prompt.

This is distinct from the general missing-encoding= issue I filed alongside this one: that one is a test/portability problem, this one changes production agent behaviour.

Suggested fix

Add encoding="utf-8" to the DEFAULT_PROMPT_PATH branch so both branches match:

python
content = Path(DEFAULT_PROMPT_PATH).read_text(encoding="utf-8").strip()

Separately, consider narrowing the except Exception or raising when DEFAULT_PROMPT_PATH was explicitly set: an operator who configured a prompt file almost certainly wants a hard failure over a silent fallback to "no custom instructions".


Found during a full-repo audit (ruff + basedpyright + pytest on a Windows host, plus manual review). Filing each finding separately so they can be triaged independently.