MemPalace/mempalace · error · ValueError

pass inline text or a file, not both

Error message

pass inline text or a file, not both

What it means

Raised by _read_text_arg() in the CLI when both an inline text argument and a file-path argument are supplied for the same piece of content. The CLI logstream commands (e.g. diary/log/event append) accept either inline text or a --*-file path (including '-' for stdin), never both; the function raises ValueError to avoid ambiguity about which content wins. The logstream contract is verbatim byte-exact content, so silently preferring one source would risk data loss.

Source

Thrown at mempalace/cli.py:1494

    """
    buffer = getattr(sys.stdout, "buffer", None)
    if buffer is None:
        sys.stdout.write(content)
        return
    sys.stdout.flush()
    buffer.write(content.encode("utf-8"))
    buffer.flush()


def _read_text_arg(inline, file_arg, default=""):
    """Resolve inline text vs --*-file (with '-' meaning stdin).

    File and stdin reads are byte-exact (see :func:`_read_stdin_exact`):
    the logstream's contract is verbatim content, so line endings must
    reach the store exactly as the author wrote them.
    """
    if inline is not None and file_arg is not None:
        raise ValueError("pass inline text or a file, not both")
    if file_arg is not None:
        if file_arg == "-":
            return _read_stdin_exact()
        return Path(os.path.expanduser(file_arg)).read_bytes().decode("utf-8")
    if inline is not None:
        return inline
    return default


def _parse_metadata_arg(raw):
    import json

    if raw is None:
        return None
    try:
        value = json.loads(raw)
    except ValueError as exc:
        raise ValueError(f"--metadata is not valid JSON: {exc}") from None

View on GitHub (pinned to 06cb6987f0)

Solutions

  1. Pass the content either inline or via the file option, not both — drop one of the two arguments
  2. If the content is on stdin, use --file - and remove the inline text
  3. Guard wrapper scripts: only set the file flag when the inline variable is empty

Example fix

# before
mempalace diary add "my note" --file note.txt

# after
mempalace diary add --file note.txt
Defensive patterns

Strategy: validation

Validate before calling

# Before calling a logstream command that routes through _read_text_arg:
if inline_text is not None and file_arg is not None:
    raise SystemExit("pass either inline text or --file, not both")
# Prefer one canonical source in scripts:
text = Path(file_arg).read_text() if file_arg else inline_text

Try / catch

try:
    text = _read_text_arg(inline, file_arg)
except ValueError as exc:
    if "not both" in str(exc):
        file_arg = None  # resolve ambiguity explicitly, then retry
        text = _read_text_arg(inline, file_arg)
    else:
        raise

Prevention

When it happens

Trigger: Calling any CLI subcommand whose handler routes through _read_text_arg(inline, file_arg) with both positional inline text and a --file option set, e.g. `mempalace diary add "some text" --file notes.txt`.

Common situations: Shell scripts that pass a default positional string and a --file flag unconditionally; copy-pasting a command template and leaving the placeholder text in place alongside the file; CI pipelines that template both arguments.

Related errors


AI-assisted analysis of MemPalace/mempalace@06cb6987f0 (2026-08-15). Data as JSON: /api/errors/693c2342cc8d6bec. Report an issue: GitHub.