Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 7:21:39 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
0
high
15
medium
36
low
MCP Server Information
Findings
This package earns a B grade with a safety score of 77/100 and carries 15 medium-severity issues alongside 36 low-severity findings, primarily related to readiness concerns. The medium-risk issues include 4 instances of ANSI escape injection vulnerability, 4 resource exhaustion risks, and 5 server configuration problems that could impact stability or security if left unaddressed. While no critical or high-severity flaws were detected, you should review and remediate the medium-severity findings before deploying this to production.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 51 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
Showing 1โ30 of 51 findings
51 findings
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 151 | A short confirmation message. |
| 152 | """ |
| 153 | |
| 154 | print(f"DEBUG: Sending email to {to}. Body length: {len(body)}") |
| 155 | return f"Email sent to {to} (mock)." |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 25 | # For now, I will return a placeholder string. |
| 26 | # </thought> |
| 27 | |
| 28 | print(f"DEBUG: Performing web search for '{query}'") |
| 29 | |
| 30 | # Mock response |
| 31 | results = f"Search results for: {query}\n1. Result A for {query}...\n2. Result B for {query}..." |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 285 | scan_report_path = ag_dir / "scan_report.json" |
| 286 | scan_payload = _build_scan_payload(report) |
| 287 | print("[1/3] Scan payload built; writing scan_report.json...", file=sys.stderr) |
| 288 | scan_report_path.write_text( |
| 289 | json.dumps(scan_payload, ensure_ascii=False, indent=2), |
| 290 | encoding="utf-8", |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 89 | # Track agent changes |
| 90 | elif event.type == "agent_updated_stream_event": |
| 91 | print( |
| 92 | f"[stream] โ Agent: {event.new_agent.name}", |
| 93 | file=sys.stderr, |
| 94 | flush=True, |
| 95 | ) |
| 96 | |
| 97 | # Handle generated items |
| 98 | elif event.type == "run_item_stream_event": |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
Full exception detail or stack trace returned to the caller. Leaking tracebacks exposes internal paths, library versions, and query structure โ useful recon for attackers.
Evidence
| 441 | result = await callables[tool_name](**arguments) |
| 442 | return True, result |
| 443 | except Exception as e: |
| 444 | return False, str(e) |
| 445 | |
| 446 | async def shutdown(self) -> None: |
| 447 | """ |
Remediation
Log the full exception server-side with a correlation ID; return only {"error_id": id, "message": "internal error"} to the caller. Never enable Flask debug mode in production.
Network / IO / subprocess call without an explicit timeout. A malicious or hung upstream (HTTP host, socket peer, child process) can pin threads, exhaust connection/process pools, and make the MCP server unresponsive. Always pass a bounded timeout. v2 extends v1 with subprocess coverage (R03 from the legacy readiness audit).
Evidence
| 58 | def run(cmd: list[str]) -> int: |
| 59 | try: |
| 60 | return subprocess.run(cmd, stderr=sys.stderr, stdout=sys.stderr).returncode |
| 61 | except FileNotFoundError: |
| 62 | return 127 |
Remediation
Pass timeout= on every call: - HTTP: `requests.get(url, timeout=5)`, `httpx.get(url, timeout=5.0)` - Node fetch: `AbortSignal.timeout(5000)` - Subprocess: `subprocess.run(["cmd"], timeout=30, check=True)` Pick a value short enough to fail fast and retry.
Network / IO / subprocess call without an explicit timeout. A malicious or hung upstream (HTTP host, socket peer, child process) can pin threads, exhaust connection/process pools, and make the MCP server unresponsive. Always pass a bounded timeout. v2 extends v1 with subprocess coverage (R03 from the legacy readiness audit).
Evidence
| 108 | script_path = shutil.which(script_name) |
| 109 | if script_path: |
| 110 | cmd = [script_path] + list(args[1:]) + ["--workspace", str(workspace)] |
| 111 | return subprocess.run(cmd, check=False).returncode |
| 112 | |
| 113 | engine_dir = _REPO_ROOT / "engine" |
| 114 | if (engine_dir / "antigravity_engine" / "__main__.py").exists(): |
Remediation
Pass timeout= on every call: - HTTP: `requests.get(url, timeout=5)`, `httpx.get(url, timeout=5.0)` - Node fetch: `AbortSignal.timeout(5000)` - Subprocess: `subprocess.run(["cmd"], timeout=30, check=True)` Pick a value short enough to fail fast and retry.
Network / IO / subprocess call without an explicit timeout. A malicious or hung upstream (HTTP host, socket peer, child process) can pin threads, exhaust connection/process pools, and make the MCP server unresponsive. Always pass a bounded timeout. v2 extends v1 with subprocess coverage (R03 from the legacy readiness audit).
Evidence
| 132 | **When** the agent attempts to execute: |
| 133 | ```python |
| 134 | import subprocess |
| 135 | subprocess.run(["rm", "-rf", "/"]) |
| 136 | ``` |
| 137 | **Then** execution is blocked before running |
| 138 | **And** error message indicates blocked import: `subprocess` |
Remediation
Pass timeout= on every call: - HTTP: `requests.get(url, timeout=5)`, `httpx.get(url, timeout=5.0)` - Node fetch: `AbortSignal.timeout(5000)` - Subprocess: `subprocess.run(["cmd"], timeout=30, check=True)` Pick a value short enough to fail fast and retry.
Network / IO / subprocess call without an explicit timeout. A malicious or hung upstream (HTTP host, socket peer, child process) can pin threads, exhaust connection/process pools, and make the MCP server unresponsive. Always pass a bounded timeout. v2 extends v1 with subprocess coverage (R03 from the legacy readiness audit).
Evidence
| 121 | "--workspace", |
| 122 | str(workspace), |
| 123 | ] |
| 124 | return subprocess.run(cmd, cwd=str(engine_dir), check=False).returncode |
| 125 | |
| 126 | console.print( |
| 127 | "[red]Engine not installed. Install: pip install ./engine " |
Remediation
Pass timeout= on every call: - HTTP: `requests.get(url, timeout=5)`, `httpx.get(url, timeout=5.0)` - Node fetch: `AbortSignal.timeout(5000)` - Subprocess: `subprocess.run(["cmd"], timeout=30, check=True)` Pick a value short enough to fail fast and retry.
Dockerfile never sets a non-root `USER` directive, so the CMD runs as root by default. Any RCE or library-level vulnerability exploited inside this container gets full privileges (MCP Top-10 R3). Add `USER <non-root>` before CMD / ENTRYPOINT in the final stage โ e.g. `USER 1000`, `USER nobody`, or `USER nonroot` on distroless.
Evidence
| 1 | # Build stage |
| 2 | FROM python:3.12-slim as builder |
| 3 | |
| 4 | WORKDIR /app |
| 5 | |
| 6 | COPY engine/ engine/ |
| 7 | RUN pip install --user --no-cache-dir ./engine |
| 8 | |
| 9 | # Runtime stage |
| 10 | FROM python:3.12-slim |
| 11 | |
| 12 | WORKDIR /app |
| 13 | |
| 14 | # Copy installed packages from builder |
| 15 | COPY --from=builder /root/.local /root/.local |
| 16 | ENV PATH=/root/.local/bin:$PATH |
| 17 | |
| 18 | # Copy application code |
| 19 | COPY . . |
| 20 | |
| 21 | # Set environment variables |
| 22 | ENV PYTHONUNBUFFERED=1 |
| 23 | |
| 24 | # Run the knowledge-hub MCP server against the mounted workspace |
| 25 | CMD ["ag-mcp", "--workspace", "/app"] |
Remediation
Create and switch to a non-root user before the CMD / ENTRYPOINT: RUN adduser --system --uid 1000 app USER 1000 Or reuse the base image's shipped non-root account (e.g. `USER nobody`, `USER nonroot` on distroless). Multi-stage builds only need the USER directive in the final stage.
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 57 | - uses: actions/checkout@v3 |
| 58 | |
| 59 | - name: Set up Python 3.12 |
| 60 | uses: actions/setup-python@v4 |
| 61 | with: |
| 62 | python-version: "3.12" |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 11 | runs-on: ubuntu-latest |
| 12 | |
| 13 | steps: |
| 14 | - uses: actions/checkout@v3 |
| 15 | |
| 16 | - name: Set up Python 3.12 |
| 17 | uses: actions/setup-python@v4 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 39 | runs-on: ubuntu-latest |
| 40 | |
| 41 | steps: |
| 42 | - uses: actions/checkout@v3 |
| 43 | |
| 44 | - name: Validate docker-compose config |
| 45 | run: docker compose config --quiet |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 54 | runs-on: ubuntu-latest |
| 55 | |
| 56 | steps: |
| 57 | - uses: actions/checkout@v3 |
| 58 | |
| 59 | - name: Set up Python 3.12 |
| 60 | uses: actions/setup-python@v4 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 14 | - uses: actions/checkout@v3 |
| 15 | |
| 16 | - name: Set up Python 3.12 |
| 17 | uses: actions/setup-python@v4 |
| 18 | with: |
| 19 | python-version: "3.12" |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1662 | if relevant: |
| 1663 | lines.append("## Code Structure (relevant excerpts)\n") |
| 1664 | lines.append(relevant) |
| 1665 | lines.append("") |
| 1666 | except Exception: |
| 1667 | pass |
| 1668 | |
| 1669 | # -- Extract from knowledge_graph.md -- |
| 1670 | kg = ag_dir / "knowledge_graph.md" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 90 | clean = _redact_secrets(message).replace("\n", " ").replace("\r", " ") |
| 91 | fd = os.open(log_path, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600) |
| 92 | try: |
| 93 | os.chmod(log_path, 0o600) |
| 94 | except OSError: |
| 95 | pass |
| 96 | with os.fdopen(fd, "a", encoding="utf-8") as handle: |
| 97 | handle.write(f"{timestamp} {clean}\n") |
| 98 | return log_path |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 641 | (ag_dir / "module_registry.md").write_text( |
| 642 | _render_module_registry_markdown(registry_entries), |
| 643 | encoding="utf-8", |
| 644 | ) |
| 645 | except Exception: |
| 646 | pass # Legacy registry is best-effort |
| 647 | except Exception as exc: |
| 648 | print(f" โ Map Agent failed: {exc}. Using fallback.", file=sys.stderr) |
| 649 | # Fallback: build map.md from file listing |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 394 | data = json.loads(pkg_text) |
| 395 | main = data.get("main") |
| 396 | if main: |
| 397 | candidates.append(main) |
| 398 | except Exception: |
| 399 | pass |
| 400 | |
| 401 | candidates.extend(_COMMON_ENTRY_FILES) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2278 | structure = "" |
| 2279 | if structure_file.is_file(): |
| 2280 | try: |
| 2281 | structure = structure_file.read_text(encoding="utf-8") |
| 2282 | except OSError: |
| 2283 | pass |
| 2284 | |
| 2285 | lines: list[str] = ["# Module Registry\n"] |
| 2286 | modules_dir = ag_dir / "modules" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2093 | try: |
| 2094 | content = mod_doc.read_text(encoding="utf-8") |
| 2095 | # Take first 800 chars โ usually contains purpose + key files |
| 2096 | parts.append(f"**Deep knowledge (excerpt):**\n{content[:800]}") |
| 2097 | except OSError: |
| 2098 | pass |
| 2099 | |
| 2100 | # Source 2: structure.md section (AST-extracted) |
| 2101 | # Use resolve_module_path for accurate directory matching |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2122 | conv_file = ag_dir / "conventions.md" |
| 2123 | if conv_file.is_file(): |
| 2124 | try: |
| 2125 | conventions = conv_file.read_text(encoding="utf-8")[:2000] |
| 2126 | except OSError: |
| 2127 | pass |
| 2128 | |
| 2129 | prompt = f"""\ |
| 2130 | You are a senior software architect. Based on the evidence below, write an |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 659 | (ag_dir / "module_registry.md").write_text( |
| 660 | _render_module_registry_markdown(registry_entries), |
| 661 | encoding="utf-8", |
| 662 | ) |
| 663 | except Exception: |
| 664 | pass |
| 665 | _mark_stage_failure( |
| 666 | refresh_status, |
| 667 | stage="module_registry", |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1795 | check=False, |
| 1796 | ) |
| 1797 | if result.returncode == 0: |
| 1798 | return result.stdout.strip() |
| 1799 | except FileNotFoundError: |
| 1800 | pass |
| 1801 | return None |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 21 | context: dict[str, str] = {} |
| 22 | for md_file in sorted(ag_dir.glob("*.md")): |
| 23 | try: |
| 24 | context[md_file.name] = md_file.read_text(encoding="utf-8") |
| 25 | except OSError: |
| 26 | pass |
| 27 | return context |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1675 | if relevant: |
| 1676 | lines.append("## Knowledge Graph (relevant excerpts)\n") |
| 1677 | lines.append(relevant) |
| 1678 | lines.append("") |
| 1679 | except Exception: |
| 1680 | pass |
| 1681 | |
| 1682 | # -- Fallback: scan report summary -- |
| 1683 | scan_report = ag_dir / "scan_report.json" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2044 | first_lines = agent_md.read_text(encoding="utf-8").splitlines()[:3] |
| 2045 | desc = " ".join(line.strip("#").strip() for line in first_lines if line.strip()) |
| 2046 | if desc: |
| 2047 | lines.append(f"**Description:** {desc[:200]}") |
| 2048 | except OSError: |
| 2049 | pass |
| 2050 | |
| 2051 | lines.append("") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 297 | binary = False |
| 298 | try: |
| 299 | with target.open("rb") as fh: |
| 300 | binary = b"\x00" in fh.read(2048) |
| 301 | except OSError: |
| 302 | pass |
| 303 | except OSError as exc: |
| 304 | return f"Error reading metadata '{file_path}': {exc}" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2079 | structure_file = ag_dir / "structure.md" |
| 2080 | if structure_file.is_file(): |
| 2081 | try: |
| 2082 | structure = structure_file.read_text(encoding="utf-8") |
| 2083 | except OSError: |
| 2084 | pass |
| 2085 | |
| 2086 | module_evidence: list[str] = [] |
| 2087 | for mod in modules: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 558 | doc_path = workspace / ".antigravity" / "module_registry.md" |
| 559 | if doc_path.is_file(): |
| 560 | try: |
| 561 | return doc_path.read_text(encoding="utf-8") |
| 562 | except OSError: |
| 563 | pass |
| 564 | return None |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 504 | doc_path = workspace / ".antigravity" / "modules" / "_git_insights.md" |
| 505 | if doc_path.is_file(): |
| 506 | try: |
| 507 | return doc_path.read_text(encoding="utf-8") |
| 508 | except OSError: |
| 509 | pass |
| 510 | return "(No pre-generated git insights available. Use your tools to explore.)" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1574 | "[retrieval] " |
| 1575 | f"files={payload.get('file_count', 0)}, " |
| 1576 | f"elapsed={payload.get('scan_elapsed_seconds', 0.0)}s" |
| 1577 | ) |
| 1578 | except Exception: |
| 1579 | pass |
| 1580 | |
| 1581 | if ("blueprint" in q.lower()) or ("ๆจกๅ" in q and "ๆณจๅ" in q): |
| 1582 | bps = _extract_blueprints_from_app(workspace) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 659 | continue |
| 660 | |
| 661 | # Fallback: treat entire top-level dir as one module |
| 662 | modules.append(item.name) |
| 663 | except OSError: |
| 664 | pass |
| 665 | |
| 666 | if list_root_module_files(root): |
| 667 | modules.append(WORKSPACE_ROOT_MODULE_ID) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 540 | doc_path = workspace / ".antigravity" / "map.md" |
| 541 | if doc_path.is_file(): |
| 542 | try: |
| 543 | return doc_path.read_text(encoding="utf-8") |
| 544 | except OSError: |
| 545 | pass |
| 546 | return None |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 77 | base = Path.home() / ".claude" / "plugins" / "data" / "antigravity-antigravity" |
| 78 | base.mkdir(parents=True, exist_ok=True) |
| 79 | try: |
| 80 | os.chmod(base, 0o700) |
| 81 | except OSError: |
| 82 | pass |
| 83 | return base / "ag-mcp.log" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 384 | scripts = data.get("project", {}).get("scripts", {}) |
| 385 | for _cmd, ref in scripts.items(): |
| 386 | mod = ref.split(":")[0].replace(".", "/") + ".py" |
| 387 | candidates.append(mod) |
| 388 | except Exception: |
| 389 | pass |
| 390 | |
| 391 | pkg_text = config_contents.get("package.json", "") |
| 392 | if pkg_text: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 353 | if total_bytes + len(text) > _CONFIG_TOTAL_LIMIT: |
| 354 | break |
| 355 | contents[rel] = text |
| 356 | total_bytes += len(text) |
| 357 | except OSError: |
| 358 | pass |
| 359 | |
| 360 | return contents |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 313 | cleaned_count += 1 |
| 314 | elif item.is_dir(): |
| 315 | shutil.rmtree(item, ignore_errors=True) |
| 316 | cleaned_count += 1 |
| 317 | except Exception: |
| 318 | pass |
| 319 | |
| 320 | console.print(f"[green]โ Cleaned {cleaned_count} temporary files/directories.[/green]") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 522 | doc_path = workspace / ".antigravity" / "structure.md" |
| 523 | if doc_path.is_file(): |
| 524 | try: |
| 525 | return doc_path.read_text(encoding="utf-8") |
| 526 | except OSError: |
| 527 | pass |
| 528 | return "(No structure map available. Run `ag-refresh --workspace /path/to/project` first.)" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 450 | check=False, |
| 451 | ) |
| 452 | if result.returncode == 0 and result.stdout.strip(): |
| 453 | parts.append("Contributors (last 3 months):\n" + result.stdout.strip()) |
| 454 | except FileNotFoundError: |
| 455 | pass |
| 456 | |
| 457 | return "\n\n".join(parts) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 256 | if readme.exists(): |
| 257 | try: |
| 258 | lines = readme.read_text(encoding="utf-8").splitlines()[:10] |
| 259 | report.readme_snippet = "\n".join(lines) |
| 260 | except OSError: |
| 261 | pass |
| 262 | break |
| 263 | |
| 264 | report.config_contents = _read_config_files(root) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 846 | files = list(dict.fromkeys( |
| 847 | f.strip() for f in result.stdout.splitlines() if f.strip() |
| 848 | ))[:20] |
| 849 | parts.append("## Recently Modified Files\n" + "\n".join(f"- {f}" for f in files)) |
| 850 | except FileNotFoundError: |
| 851 | pass |
| 852 | |
| 853 | try: |
| 854 | result = subprocess.run( |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 856 | capture_output=True, text=True, cwd=str(root), check=False, |
| 857 | ) |
| 858 | if result.returncode == 0 and result.stdout.strip(): |
| 859 | parts.append("## Contributors (3 months)\n```\n" + result.stdout.strip() + "\n```") |
| 860 | except FileNotFoundError: |
| 861 | pass |
| 862 | |
| 863 | return "\n\n".join(parts) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 132 | try: |
| 133 | for sub in d.iterdir(): |
| 134 | if sub.is_dir() and _is_venv_dir(sub): |
| 135 | venv_names.add(sub.name) |
| 136 | except OSError: |
| 137 | pass |
| 138 | return venv_names |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2307 | "architecture", "design patterns", "file locations", |
| 2308 | "key dependencies", "dependencies", |
| 2309 | ): |
| 2310 | tags.append(heading) |
| 2311 | except OSError: |
| 2312 | pass |
| 2313 | |
| 2314 | # Source 2: structure.md โ extract key filenames |
| 2315 | if not tags: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 485 | legacy_path = ag_dir / "modules" / f"{module_name}.md" |
| 486 | if legacy_path.is_file(): |
| 487 | try: |
| 488 | return legacy_path.read_text(encoding="utf-8") |
| 489 | except OSError: |
| 490 | pass |
| 491 | |
| 492 | return "(No pre-generated knowledge available. Use your tools to explore.)" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1649 | if relevant: |
| 1650 | lines.append("## Project Conventions (relevant excerpts)\n") |
| 1651 | lines.append(relevant) |
| 1652 | lines.append("") |
| 1653 | except Exception: |
| 1654 | pass |
| 1655 | |
| 1656 | # -- Extract relevant sections from structure.md -- |
| 1657 | structure = ag_dir / "structure.md" |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 465 | agent_md = ag_dir / "agents" / f"{module_name}.md" |
| 466 | if agent_md.is_file(): |
| 467 | try: |
| 468 | return agent_md.read_text(encoding="utf-8") |
| 469 | except OSError: |
| 470 | pass |
| 471 | |
| 472 | # New format: agents/{module}/ (multi-group directory) |
| 473 | agent_dir = ag_dir / "agents" / module_name |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 746 | if child.name in skip: |
| 747 | continue |
| 748 | if _dir_has_code(child, venv_dirs): |
| 749 | sub_modules.append(f"{parent_name}_{child.name}") |
| 750 | except OSError: |
| 751 | pass |
| 752 | return sub_modules |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 2245 | and f.suffix.lower() in SOURCE_CODE_EXTS |
| 2246 | and "__pycache__" not in str(f) |
| 2247 | ): |
| 2248 | files.append(f"- {f.relative_to(mod_path)}") |
| 2249 | except OSError: |
| 2250 | pass |
| 2251 | return "\n".join(files[:50]) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1685 | try: |
| 1686 | payload = json.loads(scan_report.read_text(encoding="utf-8")) |
| 1687 | file_count = int(payload.get("file_count", 0)) if isinstance(payload, dict) else 0 |
| 1688 | lines.append(f"*(Project has {file_count} files. Try rephrasing with a more specific question.)*") |
| 1689 | except Exception: |
| 1690 | pass |
| 1691 | |
| 1692 | if len(lines) <= 4: |
| 1693 | lines.append("No relevant knowledge found. Try running `ag refresh` to rebuild the knowledge base.") |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.