{"record":{"id":"1960c74dff2feb5d","repo":"abi/screenshot-to-code","slug":"invalid-eval-set-name-set-name-r-1960c7","errorCode":null,"errorMessage":"Invalid eval set name: {set_name!r}","messagePattern":"Invalid eval set name: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"backend/routes/eval_sets.py","lineNumber":153,"sourceCode":"@router.get(\"/eval-sets/{set_name}\", response_model=EvalSetDetailModel)\nasync def get_eval_set(set_name: str) -> EvalSetDetailModel:\n    try:\n        info = eval_sets.get_set(set_name)\n        if info.kind == \"text\":\n            briefs = eval_sets.list_set_briefs(set_name)\n            return EvalSetDetailModel(\n                **_set_info_to_model(info).model_dump(),\n                images=[],\n                briefs=[\n                    EvalSetBriefModel(\n                        id=b.id, title=b.title, brief=b.brief, tests=b.tests\n                    )\n                    for b in briefs\n                ],\n            )\n        images = eval_sets.list_set_images(set_name)\n    except eval_sets.InvalidSetNameError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n    except eval_sets.EvalSetNotFoundError:\n        raise HTTPException(status_code=404, detail=f\"Eval set not found: {set_name}\")\n    return EvalSetDetailModel(\n        **_set_info_to_model(info).model_dump(),\n        images=[\n            EvalSetImageModel(\n                filename=image.filename,\n                sha256=image.sha256,\n                size_bytes=image.size_bytes,\n                tags=image.tags,\n            )\n            for image in images\n        ],\n    )\n\n\n@router.get(\"/eval-sets/{set_name}/images/{filename}\")\nasync def get_eval_set_image(set_name: str, filename: str) -> FileResponse:","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/backend/routes/eval_sets.py#L135-L171","documentation":"Surfaces from evals.sets._validate_set_name() via GET /eval-sets/{set_name} as a 400. Set names must match ^[A-Za-z0-9][A-Za-z0-9._ -]*$ (first char alphanumeric, then alphanumerics, dot, underscore, space, hyphen) because the name is joined into filesystem paths — the pattern blocks traversal. The same exception type also carries messages about invalid brief entries, but this route's variant is the name check.","triggerScenarios":"GET /eval-sets/{set_name} where set_name starts with '.', '-', or '/', contains slashes or '..', or is empty — e.g. '../secrets', '-evals', '.hidden'.","commonSituations":"URL-encoding issues turning spaces into %20 mishandled; names taken from directory listings of non-set dirs; attempted traversal probes; names with slashes from nested paths.","solutions":["Use a name matching ^[A-Za-z0-9][A-Za-z0-9._ -]*$ such as 'jun-21-evals' or 'Landing Pages v2'.","List valid names first via GET /eval-sets and pick from the response.","URL-encode the path segment properly (spaces allowed but must be encoded in URLs).","Never send leading dots/hyphens or path separators."],"exampleFix":"# before\nGET /eval-sets/../other-dir  # 400 Invalid eval set name\n\n# after\nimport re\nassert re.match(r\"^[A-Za-z0-9][A-Za-z0-9._ -]*$\", set_name), \"bad set name\"\nGET /eval-sets/Landing%20Pages%20v2","handlingStrategy":"validation","validationCode":"import re\nSET_NAME_RE = re.compile(r\"^[A-Za-z0-9][A-Za-z0-9._ -]*$\")\n\ndef is_valid_set_name(name: str) -> bool:\n    return bool(SET_NAME_RE.match(name))\n\nif not is_valid_set_name(set_name):\n    raise ValueError(f\"invalid eval set name: {set_name!r}\")","typeGuard":"def is_valid_set_name(name: object) -> bool:\n    \"\"\"First char alphanumeric; then alnum . _ space - only.\"\"\"\n    return (\n        isinstance(name, str)\n        and bool(re.match(r\"^[A-Za-z0-9][A-Za-z0-9._ -]*$\", name))\n    )","tryCatchPattern":"resp = requests.get(url + f\"/eval-sets/{set_name}\")\nif resp.status_code == 400:\n    raise ValueError(f\"set name rejected: {set_name!r}\")\nresp.raise_for_status()","preventionTips":["Pick set names like 'jun-21-evals' or 'Landing Pages v2'; never leading . or -, never slashes.","Choose names from GET /eval-sets rather than typing them.","URL-encode spaces when putting set names in URLs."],"tags":["fastapi","http-400","validation","path-traversal","eval-sets"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}