ArchiveBox/ArchiveBox · error · ValueError

error_message (from validate_persona_name)

Error message

error_message (from validate_persona_name)

What it means

sync_persona (POST /api/v1/persona/sync) strips the requested persona name and validates it with validate_persona_name, raising ValueError(error_message) on failure. The validator rejects empty names, path separators (/ or \), parent-directory references (..), leading dots, and null bytes/newlines, because persona names become directory names under PERSONAS_DIR and must not enable path traversal.

Source

Thrown at archivebox/api/v1_personas.py:136

@paginate(CustomPagination)
def get_personas(request: HttpRequest):
    """List personas available on this ArchiveBox server."""
    return Persona.objects.all().order_by("name")


@router.post("/sync", response=PersonaSyncResponseSchema, url_name="sync_persona")
def sync_persona(request: HttpRequest, payload: PersonaSyncSchema):
    """
    Create or update a Persona from a browser extension profile export.

    The extension sends browser settings plus portable auth artifacts. The server
    keeps browser override settings in Persona.config and writes cookies.txt /
    auth.json into the persona directory for extractors to consume.
    """
    name = payload.name.strip()
    is_valid, error_message = validate_persona_name(name)
    if not is_valid:
        raise ValueError(error_message)

    persona = find_persona(payload.extension_persona_id, name)
    created = persona is None
    if persona is None:
        persona = Persona(name=name)
        if request.user.is_authenticated:
            persona.created_by = request.user

    persona.config = {
        **(persona.config or {}),
        **browser_settings_to_config(payload.extension_persona_id, payload.settings),
    }
    persona.save()
    persona.ensure_dirs()

    cookies_written = False
    if payload.cookies_txt.strip():
        (persona.path / "cookies.txt").write_text(payload.cookies_txt)

View on GitHub (pinned to 74564b2822)

Solutions

  1. Sanitize the persona name: strip whitespace, remove/replace path separators, leading dots, and '..' before calling the API
  2. Use a simple slug of the name (letters, digits, dashes, underscores) e.g. 'work-profile' instead of 'work/profile'
  3. Pre-validate with the same rules as validate_persona_name (archivebox/cli/archivebox_persona.py:159) client-side to get a friendlier error

Example fix

// before
{"name": "profiles/work"}
// after
{"name": "profiles-work"}
Defensive patterns

Strategy: validation

Validate before calling

function validatePersonaName(name) {
  const n = name.trim();
  if (!n) return 'Persona name cannot be empty';
  if (/[\/\\]/.test(n)) return 'no path separators';
  if (n.includes('..')) return 'no parent references';
  if (n.startsWith('.')) return 'no leading dot';
  if (/[\x00\n\r]/.test(n)) return 'invalid characters';
  return null;
}

Type guard

const isValidPersonaName = (name) => {
  const n = name.trim();
  return n.length > 0 && !/[\/\\]/.test(n) && !n.includes('..') && !n.startsWith('.') && !/[\x00\n\r]/.test(n);
};

Try / catch

try {
  await syncPersona({ name });
} catch (e) {
  if (e instanceof ValueError || /Persona name/i.test(e.message)) {
    // sanitize: slugify the name and retry once
    return syncPersona({ name: slugify(name) });
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /api/v1/persona/sync with payload.name that is: empty/whitespace, contains '/' or '\\', contains '..', starts with '.', or contains \x00 / \n / \r characters.

Common situations: Deriving a persona name from a URL or file path without sanitizing it (e.g. 'profiles/alice' or '../default'); users entering names with leading dots like '.chrome-default'; passing empty name fields from form submissions.

Related errors


AI-assisted analysis of ArchiveBox/ArchiveBox@74564b2822 (2026-08-28). Data as JSON: /api/errors/7d62600a3c780839. Report an issue: GitHub.