{"record":{"id":"e004e8c25665db7e","repo":"slint-ui/slint","slug":"tool-not-found-needed-by-features","errorCode":null,"errorMessage":"${tool} not found, needed by: ${features}","messagePattern":"(.+?) not found, needed by: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/build-demo-images.py","lineNumber":212,"sourceCode":"        env[\"PATH\"] = os.pathsep.join(\n            entry for entry in env[\"PATH\"].split(os.pathsep) if entry != uv_bin\n        )\n    return env\n\n\ndef check_tools(boards: list[Board]) -> None:\n    \"\"\"Abort before any build if a conversion tool the selected boards need is missing.\n\n    The shell version warned here and then died mid-run, after minutes of cargo builds.\n    \"\"\"\n    needed: dict[str, list[str]] = {}\n    for board in boards:\n        tool = CONVERTERS[board.kind]\n        if tool and not shutil.which(tool):\n            needed.setdefault(tool, []).append(board.feature)\n    if needed:\n        for tool, features in needed.items():\n            warn(f\"{tool} not found, needed by: {', '.join(features)}\")\n        sys.exit(\"aborting: install the missing tools, or narrow the run with --only\")\n\n\ndef build_board(board: Board, out: Path) -> None:\n    log(f\"printerdemo_mcu: {board.feature} ({board.kind} / {board.target})\")\n    cargo = [\"cargo\"]\n    env = build_env()\n    if board.kind == \"esp\":\n        cargo += [\"+esp\"]\n    elif board.kind == \"stm\":\n        # STM keeps Slint's textures in external OSPI flash (.slint_assets); otherwise\n        # rodata overflows the internal flash. Only the stm32* boards define it.\n        env = build_env(SLINT_ASSET_SECTION=\".slint_assets\")\n    cargo += [\n        \"build\",\n        \"--manifest-path\",\n        \"demos/Cargo.toml\",\n        \"-p\",","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/scripts/build-demo-images.py#L194-L230","documentation":"check_tools in scripts/build-demo-images.py verifies that the flash/converter tool required by each selected board kind (from the CONVERTERS mapping) is available via shutil.which. If one or more tools are missing, it warns '<tool> not found, needed by: <features>' for each and aborts the whole run with a non-zero exit before building anything. This is a deliberate pre-flight gate so builds fail early with an actionable message.","triggerScenarios":"Running scripts/build-demo-images.py (without --only narrowing) on a machine where a required tool such as a probe/flasher or image converter for a selected board kind is not installed or not on PATH.","commonSituations":"Fresh CI container or new dev machine missing the vendor flashing tools; tool installed via a version manager whose bin dir is not on PATH in the script's environment; requesting boards whose converter was never installed because only one target was needed.","solutions":["Install the named tool and ensure it is on PATH (verify with which <tool>)","Re-run with --only <features> to select only boards whose tools you have","Fix PATH in the script's environment (CI: add tool install step)","Check CONVERTERS mapping matches the tool name actually installed"],"exampleFix":"# before\npython3 scripts/build-demo-images.py\n# aborting: install the missing tools, or narrow the run with --only\n# after\npython3 scripts/build-demo-images.py --only esp32-s3-team-industrial-solution-board","handlingStrategy":"validation","validationCode":"import shutil\nmissing = [t for t in set(CONVERTERS.values()) if t and not shutil.which(t)]\nif missing:\n    raise SystemExit(f\"missing tools: {missing}; install them or use --only\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install all CONVERTERS tools in your dev image / CI container","Run the script with --only for the boards you can actually build","Add a pre-flight tool check to CI before the build job","Keep tool installation documented in the repo README"],"tags":["build","tooling","prerequisites","cli"],"backgroundTag":"missing-dependency","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}