You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow file fields on env-configured instances - #836
An instance that exists only because of UN_* is no longer a locked card. Fields the environment owns stay disabled and are left out of the save, so the URL, API key, and other env values are not copied into the config file. Fields the environment does not set, such as a name or timeout, can be edited and are written to the file.
Unchanged env-only rows are still omitted from Save, so saving an unrelated setting does not create a file entry for them. Remove stays hidden on those rows because deleting the card does not remove the environment variables, and the instance comes back on the next overlay.
PUT of a Sonarr row that has only a name and timeout, while URL and API key stay in the environment, keeps those secrets out of the file and on the live instance.
Probably causes more problems. 😓 Some of this is frickin complicated because we have to deal with things like lists. If a list item is set in an env var, can the config file add to it? Not very easily. Because then we have to deal with frontend and backend validators. Does the Starr instance have a url? No, but it's in the env. We don't save env vars to the config file, so we have to validate after merging the values, then save only the non-env values. sheesh. There's probably some bugs in this, and I really don't like it. But it needs to get worked out.
Test plan
Configure Sonarr with UN_SONARR_0_URL, UN_SONARR_0_API_KEY, and UN_SONARR_0_PATHS_0 only. The URL, key, and paths stay locked. Set a timeout and save. The timeout sticks, and the config file does not gain the URL or API key.
Save the page without editing that Sonarr. It does not appear as a new file entry.
go test -count=1 -run TestConfigPutEnvOnlySonarrAcceptsFileFields ./pkg/unpackerr/
The reason will be displayed to describe this comment to others. Learn more.
Reviewed head 7f12286 against base e6cf9d7: FoldersForm.svelte, HooksForm.svelte, StarrForm.svelte, the comment fixes in slug.ts, and the new sonarr test in configput_test.go. Also read the machinery behind all three forms — env.svelte.ts, Input.svelte, hooktmpl.ts, and on the Go side configput.go, webhook.go, apps.go, hooks/validate.go, start.go.
What the diff actually is. The backend already accepted file fields on env-only instances: I ran the new TestConfigPutEnvOnlySonarrAcceptsFileFields against base and it passes there too, so it pins existing behavior rather than testing a change. Everything substantive is in the three settings forms: whole-card locking of env-only rows is gone, per-field env ownership still locks via Input's envVar/envHas, unchanged rows are omitted from the payload by comparing against the orig snapshot (which now has to be taken aftermergeEnvOnlyRows, hence the moved assignments), and only persisted rows flip envOnly off. omitEnvFields keeps env values out of the file. That is the entire change, plus the #831 item-3 origin.
Executed validation.go test ./... green at head (new test included); the same test green at base. npm ci + svelte-check clean, vitest 45/45, vite build clean. All ten public CI check-runs on 7f12286 are green, including the three golangci-lint jobs I did not run locally. Beyond the suites, I built and ran the head server with UN_SONARR_0_URL/UN_SONARR_0_API_KEY env-only, a pushover env webhook, and a partial UN_WEBHOOK_1_TOKEN-only hook, and verified rendered states via DOM assertions rather than trusting the code alone:
Env-owned Sonarr fields render locked with the live env values; name, path, timeout, maxBytes etc. are editable. The feature works as described.
All three open Copilot findings below reproduce live on this build.
On the three open comments from Copilot — all confirmed, and none are regressions versus base, since env-only cards were fully locked before.
Incomplete env hooks block saves (HooksForm.svelte:107). Verified: validateApps warns only on ErrWebhookNoURL (apps.go), so a token-only env hook stays in the live view, its blank idField fails validation, and Save disables for the whole section. Screenshot shows exactly that: card 1 invalid, Save greyed out, while the healthy pushover hook above it could not be saved either. It is escapable — the missing URL is now an editable file field, and any successful PUT drops such leftovers via dropInvalidEnvOverlay — but given your "probably causes more problems" note I think you should make the call on purpose: keep the block, or keep skipping env-only rows in invalid the way FoldersForm effectively does through its env-aware path check.
Env-only hooks render the wrong profile (HooksForm.svelte:573). Confirmed live: the pushover env hook shows the default chip and no token/channel/nickname controls, so non-env extras on such hooks remain unreachable whenever TEMPLATE or URL is env-owned. If you want to close this without copying env values into the file, derive the profile from env values for env-only rows — e.g. hookFormProfile(envHas(TEMPLATE) ? envLiveValue(TEMPLATE) : hook.template, envHas(URL) ? envLiveValue(URL) : hook.url, hook.templatePath); URL sniffing alone recovers pushover/discord/slack/telegram/notifiarr.
valid_ssl invisible on https env-only Starr instances (StarrForm.svelte:450). Confirmed: the .ssl-addon button does not render even though the env URL is https, because the condition reads the blank file value. One-line fix: gate on the effective URL, (envLiveValue(envField(envPrefix, slug, 'URL')) ?? app.url).startsWith('https://').
One small extra I found:omitEnvFields (slug.ts:118) uses envOwnsExact, which does not match indexed children, so saving any field on a folder configured with FOLDER_0_EXCLUDE_PATH_0 writes blank exclude_paths: [] / wait_extensions: [] into the file. No runtime impact since env still overlays, but it cuts against the PR's own "env is not copied into the file" principle; worth making envOwnsExact treat envHas-style child matches as owned.
None of this blocks approval: the diff is strictly more capable than base for env-only instances, the skip-if-unchanged and omitEnvFields invariants hold, and I found no correctness or data-loss defect in it. Approving; the notes above are yours to triage, with the ssl-toggle fix the most time-sensitive.
The reason will be displayed to describe this comment to others. Learn more.
Yes — validated, and both of Copilot's open comments reproduce on this head.
Executed: go test -count=1 ./pkg/unpackerr/ (ok, 4.8s, includes TestConfigPutEnvOnlySonarrAcceptsFileFields), npm ci + vite build for the UI, built the binary from a050f33, ran it with UN_SONARR_0_URL=https://127.0.0.1:9999, UN_SONARR_0_API_KEY=<36 chars>, UN_SONARR_0_VALID_SSL=true, and drove the settings pages in headless Chrome over CDP.
SSL addon (the one you asked about): the button renders because the env URL is https, but it is disabled and unchecked, aria-pressed="false", since the checkbox reads app.valid_ssl from blank(). The live config does verify certs (startup log: verify_ssl:true). Mirror what the URL field does: when envHas(…VALID_SSL), drive checked/aria from envLiveValue(…VALID_SSL) === 'true'.
Hooks comment is real too: with only UN_WEBHOOK_0_URL=https://notifiarr.com/… set, the Notifiarr profile chip appears but the dedicated key field is hidden (hookShowsApiKey reads the file URL only), and the headers editor is hidden as well, since hookShowsHeaders treats the auto-detected case as source 'default', not 'named'. The only unblock today is typing template = "notifiarr" into the file, which at least surfaces the headers editor for X-Api-Key.
Neither one can write an env-owned value to disk, omitEnvFields still strips them and the Go tests assert it, so these are display/workflow gaps in the new file-fields feature rather than data bugs. Still worth fixing before this ships: users of exactly the env-configured setups this PR targets will see their SSL validation rendered as off and have no visible way to add a Notifiarr key.
An unchanged env-only hook with a valid slug such as constructor is omitted from payload, but this lookup finds an inherited property and marks it as file-backed. Remove then appears, and a later Save can persist the untouched hook; use Object.hasOwn(payload, row.slug) instead. Apply the same own-property check in FoldersForm.svelte:283 and StarrForm.svelte:336.
Resolve filepath-backed profile fields from live values
For UN_WEBHOOK_0_URL=filepath:/run/secrets/webhook-url, envLiveValue() returns the literal reference rather than the expanded URL. If that file contains a Pushover URL and no explicit template is set, the env-only row gets the Notifiarr profile and hides the editable token, channel, and nickname controls. Resolve filepath-backed profile fields from a separate snapshot of the already-fetched /live response, keeping expanded values out of the save model.
Use effective filepath URL for SSL toggle visibility
An env-only HTTPS instance still cannot edit certificate validation when its URL comes from UN_SONARR_0_URL=filepath:/run/secrets/sonarr-url. /api/config/env retains that literal reference, so this check sees filepath: rather than the expanded https:// URL and hides the SSL toggle even when VALID_SSL is not env-owned. Use a separate effective URL from the already-fetched /live data for this visibility check without copying it into the file payload.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
UN_*is no longer a locked card. Fields the environment owns stay disabled and are left out of the save, so the URL, API key, and other env values are not copied into the config file. Fields the environment does not set, such as a name or timeout, can be edited and are written to the file.PUTof a Sonarr row that has only a name and timeout, while URL and API key stay in the environment, keeps those secrets out of the file and on the live instance.Test plan
UN_SONARR_0_URL,UN_SONARR_0_API_KEY, andUN_SONARR_0_PATHS_0only. The URL, key, and paths stay locked. Set a timeout and save. The timeout sticks, and the config file does not gain the URL or API key.go test -count=1 -run TestConfigPutEnvOnlySonarrAcceptsFileFields ./pkg/unpackerr/golangci-lint run ./pkg/unpackerr/Made with Cursor