{"record":{"id":"0ec9479fea320077","repo":"langflow-ai/langflow","slug":"could-not-strip-ruff-per-file-ignore-entry-for-ri","errorCode":null,"errorMessage":"Could not strip ruff per-file-ignore entry for {ri.pattern!r}; the regex may not match the current layout.  Edit by hand.","messagePattern":"Could not strip ruff per-file-ignore entry for (.+?); the regex may not match the current layout\\.  Edit by hand\\.","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/migrate/port_bundle.py","lineNumber":1113,"sourceCode":"        return actions\n    text = ROOT_PYPROJECT.read_text(encoding=\"utf-8\")\n    for ri in plan.ruff_ignores:\n        # Remove the entire entry block (``\"<pattern>\" = [...]\\n``);\n        # the block may span multiple lines so we anchor on the\n        # pattern line and consume up to the closing ``]\\n``.\n        # The bracketed body may contain newlines, so use re.DOTALL.\n        block = re.compile(\n            r'^\"' + re.escape(ri.pattern) + r'\"\\s*=\\s*\\[[^\\]]*\\]\\n',\n            re.MULTILINE | re.DOTALL,\n        )\n        new_text = block.sub(\"\", text, count=1)\n        if new_text == text:\n            msg = (\n                f\"Could not strip ruff per-file-ignore entry for \"\n                f\"{ri.pattern!r}; the regex may not match the current \"\n                \"layout.  Edit by hand.\"\n            )\n            raise SystemExit(msg)\n        text = new_text\n    ROOT_PYPROJECT.write_text(text, encoding=\"utf-8\")\n    return actions\n\n\n# ---------------------------------------------------------------------------\n# Phase C: workspace + external consumers\n# ---------------------------------------------------------------------------\n\n\ndef _insert_before_marker(text: str, end_marker: str, payload: str, *, what: str) -> str:\n    needle = end_marker\n    idx = text.find(needle)\n    if idx == -1:\n        msg = (\n            f\"Could not locate the {what} end marker ({needle!r}) in \"\n            \"pyproject.toml.  Re-add the ``langflow-extensions:bundle-*`` \"\n            \"marker pair before re-running -- see src/bundles/PORTING.md.\"","sourceCodeStart":1095,"sourceCodeEnd":1131,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/scripts/migrate/port_bundle.py#L1095-L1131","documentation":"As part of porting, port_bundle.py removes the ported provider's per-file-ignore entry (a quoted glob followed by '= [ ... ]') from the ruff config in the root pyproject.toml, using a regex with re.MULTILINE|re.DOTALL. If the substitution changes nothing — the entry's formatting no longer matches the expected 'pattern\" = [ ... ]\\n' layout — the script refuses to write an unmodified file and tells you to edit by hand, because silently continuing would leave stale lint ignores.","triggerScenarios":"Running port_bundle.py --apply when the root pyproject.toml's ruff per-file-ignores section has been reformatted (different quote nesting, inline brackets, comment inside the list, or the pattern string escaped differently) so the generated regex no longer matches.","commonSituations":"A formatting tool or editor reflowed pyproject.toml between the time the ignore entry was added and the port; hand-edits that changed indentation or added comments inside the bracket body; regex-hostile characters in the glob.","solutions":["Open pyproject.toml, find the per-file-ignores entry matching the pattern quoted in the error, and delete that entry (the whole quoted-key = [ ... ] block) manually.","Then re-run port_bundle.py --apply; the strip step becomes a no-op once the entry is gone.","Keep per-file-ignore bodies free of inline comments and exotic formatting so the mechanical strip keeps working."],"exampleFix":"# before (pyproject.toml)\n[tool.ruff.lint.per-file-ignores]\n\"src/lfx/src/lfx/components/agentics/**\" = [\n    \"RUF012\",  # keep for now\n]\n\n# after (pyproject.toml) — entry removed by hand\n[tool.ruff.lint.per-file-ignores]\n# (agentics entry deleted; bundle owns its own ruff config now)","handlingStrategy":"fallback","validationCode":"import re\nfrom pathlib import Path\n\ndef per_file_ignore_entry_matches(text: str, pattern: str) -> bool:\n    block = re.compile(\n        r'^\"' + re.escape(pattern) + r'\"\\s*=\\s*\\[[^\\]]*\\]\\n',\n        re.MULTILINE | re.DOTALL,\n    )\n    return block.search(text) is not None or f'\"{pattern}\"' not in text","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep ruff per-file-ignore entries on a single canonical format: quoted glob, ' = [', flags, ']' — no comments inside the brackets.","Revert pyproject.toml formatting changes (prettier/taplo) before running --apply migrations.","When the guard fires, edit pyproject.toml by hand first, then re-run — the script will proceed once the entry is gone."],"tags":["migration","ruff","pyproject","regex","formatting"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}