Skip to content

fix(docker): guard primary container name access#1977

Merged
elibosley merged 3 commits intomainfrom
codex/fix-nameless-docker-template-scan
Mar 30, 2026
Merged

fix(docker): guard primary container name access#1977
elibosley merged 3 commits intomainfrom
codex/fix-nameless-docker-template-scan

Conversation

@elibosley
Copy link
Copy Markdown
Member

@elibosley elibosley commented Mar 30, 2026

Summary

  • centralize Docker primary-name lookup behind shared helpers in the API and web app
  • guard Docker scanner, resolver, service, organizer, and UI paths that previously read names[0] directly
  • preserve organizer resource IDs by keeping slash-prefixed names where that existing behavior is required
  • apply the small Prettier follow-up needed for the API and web CI lint jobs to pass

Root cause

Docker can report stale or malformed container metadata with an empty or missing primary name. Several code paths assumed names[0] always existed, which made the template scan brittle and left a few related API/UI flows exposed to the same failure mode.

Verification

  • cd api && pnpm run lint
  • cd api && pnpm run test
  • cd web && pnpm run build
  • cd web && pnpm run lint

Summary by CodeRabbit

  • Bug Fixes

    • Scanner and sync workflows now skip nameless containers without errors and avoid incorrect template/mapping updates.
  • Tests

    • Added tests covering containers with missing/empty names and ensuring correct scan/sync behavior and name-normalization edge cases.
  • Refactor

    • Centralized primary-container name extraction and updated UI and services to use it for consistent name display and lookup.

- Purpose: prevent Docker template sync from crashing when Docker reports a container without a primary name.
- Before: the scanner assumed container.names[0] always existed and called .replace() on it during sync and template matching.
- Why that was a problem: stale or malformed Docker metadata could make container.names[0] undefined, which crashed the scanner and bubbled the failure into mothership-backed API flows.
- What changed: nameless containers are now skipped for name-based mapping, repository-only matching still works, and the regression is covered with scanner tests.
- How it works: normalizeContainerName now returns null for missing names, scan/sync use a shared helper to guard primary-name access, and tests cover empty-name containers end-to-end.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8c7660e9-fc48-4333-88ab-f5da182dbee4

📥 Commits

Reviewing files that changed from the base of the PR and between b70fc5e and 1473a95.

📒 Files selected for processing (19)
  • api/src/unraid-api/graph/resolvers/docker/docker-autostart.service.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-container.resolver.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-port.service.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.spec.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts
  • api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts
  • api/src/unraid-api/graph/resolvers/docker/docker.service.spec.ts
  • api/src/unraid-api/graph/resolvers/docker/docker.service.ts
  • api/src/unraid-api/graph/resolvers/docker/organizer/docker-organizer.service.ts
  • api/src/unraid-api/graph/resolvers/docker/utils/docker-container-name.ts
  • web/src/components/Docker/ContainerOverviewCard.vue
  • web/src/components/Docker/ContainerSizesModal.vue
  • web/src/components/Docker/DockerAutostartSettings.vue
  • web/src/components/Docker/DockerContainerManagement.vue
  • web/src/components/Docker/DockerContainersTable.vue
  • web/src/components/Docker/DockerOrphanedAlert.vue
  • web/src/composables/useDockerEditNavigation.ts
  • web/src/composables/useDockerRowActions.ts
  • web/src/utils/docker.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


Walkthrough

Centralized Docker container primary-name extraction was introduced and propagated across backend services and web UI. Logic now returns null for missing names; nameless containers are skipped in scanning/syncing and fallback matching by repository is preserved. Tests expanded to cover null/empty-name scenarios.

Changes

Cohort / File(s) Summary
Name utility (new)
api/src/unraid-api/graph/resolvers/docker/utils/docker-container-name.ts
Added helpers: stripLeadingDockerSlash, getDockerContainerPrimaryName, and getNormalizedDockerContainerPrimaryName. These provide nullable, configurable primary-name extraction and normalization.
Template scanner & tests
api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts, api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.spec.ts
Scanner now uses nullable primary-name helper; containers without a primary name are skipped (result.skipped++) and excluded from sync sets; name-based template matching is conditional, falling back to repository/image matching. Tests added/updated to assert nameless handling and null normalization.
Backend: services & resolvers (name extraction delegation)
api/src/unraid-api/graph/resolvers/docker/docker-autostart.service.ts, api/src/unraid-api/graph/resolvers/docker/docker-container.resolver.ts, api/src/unraid-api/graph/resolvers/docker/docker-port.service.ts, api/src/unraid-api/graph/resolvers/docker/docker.resolver.ts, api/src/unraid-api/graph/resolvers/docker/docker.service.ts, api/src/unraid-api/graph/resolvers/docker/organizer/docker-organizer.service.ts
Replaced inline/duplicated logic that used names[0] and manual slash/locale normalization with centralized helpers; adjusted fallbacks where applicable (some fallbacks changed to container.id or null-aware checks). No public signatures changed.
Backend tests/mocks
api/src/unraid-api/graph/resolvers/docker/docker.service.spec.ts
Mocks updated to delegate primary-name extraction to the shared helper rather than duplicate inline heuristics.
Web UI: utilities
web/src/utils/docker.ts
Added getPrimaryContainerName wrapper and updated internal usages (getRowDisplayLabel, toContainerTreeRow) to use it.
Web UI: components & composables
web/src/components/Docker/... (ContainerOverviewCard.vue, ContainerSizesModal.vue, DockerAutostartSettings.vue, DockerContainerManagement.vue, DockerContainersTable.vue, DockerOrphanedAlert.vue), web/src/composables/useDockerEditNavigation.ts, web/src/composables/useDockerRowActions.ts
Replaced direct names[0] + stripLeadingSlash usage with getPrimaryContainerName(...) across multiple components and composables to standardize primary-name derivation and display. Behavior/fallbacks preserved where applicable.
Tests coverage note
...docker-template-scanner.service.spec.ts
Expanded to cover normalizeContainerName null/empty inputs, scanTemplates skipping nameless containers, and syncMissingContainers behavior when primary names are missing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I dug a hole in code so neat,
Where names might vanish, yet we meet.
I nudge the scanner, soft and small,
Skip nameless ones — no crash at all.
Hop, tests applaud — null-safe and sweet.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(docker): tolerate nameless containers in template scans' directly and clearly summarizes the main change: adding tolerance for containers without names in Docker template scanning.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-nameless-docker-template-scan

Comment @coderabbitai help to get the list of available commands and usage tips.

- Purpose: centralize Docker primary-name lookup so nameless containers no longer crash template scanning or related flows.
- Before: multiple API and web call sites read names[0] directly or duplicated slash-stripping logic with inconsistent fallback behavior.
- Problem: containers without a first Docker name could break scans, resolver paths, and UI interactions, and the duplicated logic made regressions easy to miss.
- Now: API and web Docker code route name lookup through shared helpers, preserving organizer ID semantics where the leading slash is expected while safely handling missing names elsewhere.
- How: added a reusable Docker name helper, updated the Docker scanner/service/resolver/autostart/port and organizer code plus affected web components/composables, and refreshed tests/fixtures to cover nameless containers safely.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts (1)

295-297: Consider reducing warning noise for persistent nameless containers

Line 295 logs a warning every time this helper is hit; on systems with stale nameless containers this can flood logs during periodic sync/scan. Consider debug level or dedupe-by-container-id logging.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts`
around lines 295 - 297, The repeated warning comes from the
docker-template-scanner.service logging "Skipping container ${container.id}...
no primary Docker name" on every scan; change this to reduce noise by either
lowering it to logger.debug or implementing a one-time warning per container id:
add a Set (e.g., loggedNamelessContainerIds) as a private field on the
DockerTemplateScannerService class and, in the helper that currently calls
logger.warn, check/set that Set and only log once per container.id (or use
logger.debug instead if dedupe is not desired). Ensure you update references to
container.id and logger.warn in the helper to use the new Set/check or debug
call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts`:
- Around line 295-297: The repeated warning comes from the
docker-template-scanner.service logging "Skipping container ${container.id}...
no primary Docker name" on every scan; change this to reduce noise by either
lowering it to logger.debug or implementing a one-time warning per container id:
add a Set (e.g., loggedNamelessContainerIds) as a private field on the
DockerTemplateScannerService class and, in the helper that currently calls
logger.warn, check/set that Set and only log once per container.id (or use
logger.debug instead if dedupe is not desired). Ensure you update references to
container.id and logger.warn in the helper to use the new Set/check or debug
call.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 45958d2f-87d1-48b6-974c-571d45b37f26

📥 Commits

Reviewing files that changed from the base of the PR and between 7f04f8e and b70fc5e.

📒 Files selected for processing (2)
  • api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.spec.ts
  • api/src/unraid-api/graph/resolvers/docker/docker-template-scanner.service.ts

- Purpose: unblock the failing PR checks after the shared Docker name helper landed.

- Before: the logic changes were correct, but a few API imports/line wraps and one Vue file were not formatted the way CI expects.

- Why that was a problem: the Test API lint step and Build Web App lint step both failed, so the branch looked broken even though the behavior and tests were fine.

- What changed: applied the exact Prettier formatting CI wanted in the Docker resolver/helper/organizer files and the Docker containers table.

- How it works: no runtime behavior changed; this commit only normalizes formatting so the existing lint/build pipeline passes.
@elibosley elibosley changed the title fix(docker): tolerate nameless containers in template scans fix(docker): guard primary container name access Mar 30, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 65.68627% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.10%. Comparing base (7f04f8e) to head (1473a95).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...rc/components/Docker/DockerContainerManagement.vue 0.00% 6 Missing ⚠️
...ph/resolvers/docker/utils/docker-container-name.ts 82.75% 5 Missing ⚠️
web/src/utils/docker.ts 0.00% 5 Missing ⚠️
.../src/components/Docker/DockerAutostartSettings.vue 0.00% 4 Missing ⚠️
web/src/components/Docker/DockerOrphanedAlert.vue 0.00% 3 Missing ⚠️
...nraid-api/graph/resolvers/docker/docker.service.ts 50.00% 2 Missing ⚠️
web/src/components/Docker/ContainerSizesModal.vue 0.00% 2 Missing ⚠️
...eb/src/components/Docker/DockerContainersTable.vue 0.00% 2 Missing ⚠️
web/src/composables/useDockerEditNavigation.ts 0.00% 2 Missing ⚠️
web/src/composables/useDockerRowActions.ts 0.00% 2 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1977      +/-   ##
==========================================
+ Coverage   52.08%   52.10%   +0.02%     
==========================================
  Files        1031     1032       +1     
  Lines       71564    71616      +52     
  Branches     8090     8105      +15     
==========================================
+ Hits        37275    37318      +43     
- Misses      34164    34173       +9     
  Partials      125      125              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1977/dynamix.unraid.net.plg

@elibosley elibosley merged commit 7dadaa2 into main Mar 30, 2026
12 checks passed
@elibosley elibosley deleted the codex/fix-nameless-docker-template-scan branch March 30, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant