firebase / firebase/firebase-tools
functions params: select prompt ignores a non-string default and preselects the first option
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.3k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 84
Description
### [REQUIRED] Environment info
**firebase-tools:** 15.26.0 (code is unchanged on `main` at ecda4df)
**Platform:** Windows (not platform specific)
### [REQUIRED] Test case
A non-string param with a `select` input whose `default` is not the first option:
```ts
import { defineBoolean, select } from "firebase-functions/params";
export const makePublic = defineBoolean("MAKE_PUBLIC", {
label: "Make resized images public",
default: false,
input: select({ Yes: true, No: false }),
});
```
### [REQUIRED] Steps to reproduce
1. Declare the param above in a functions codebase.
2. Run `firebase deploy --only functions` with `MAKE_PUBLIC` unset so the CLI prompts for it.
3. Observe which option is highlighted, then press Enter.
### [REQUIRED] Expected behavior
"No" is preselected, since the declared default is `false`. Pressing Enter stores `MAKE_PUBLIC=false`.
### [REQUIRED] Actual behavior
"Yes" (the first option) is preselected. Pressing Enter stores `MAKE_PUBLIC=true`.
Cause: `promptSelect` passes the resolved default to inquirer unchanged but stringifies every option value, so a boolean or number default never matches a choice and inquirer falls back to the first one.
https://github.com/firebase/firebase-tools/blob/ecda4df52cc2f5b9d124f1fbe654ee053db55333/src/deploy/functions/params.ts#L914-L928
```ts
const response = await select({
default: resolvedDefault as string,
...
choices: input.select.options.map((option) => ({
value: option.value.toString(),
```
Affects `defineBoolean` and `defineInt` selects; string selects are fine. Any param whose default is the first option looks correct by coincidence, which is why this is easy to miss.
Suggested fix: `default: resolvedDefault?.toString()` (or compare against `option.value` before stringifying). `promptSelectMultiple` (L953) has the same pattern for `defineList` defaults.
Found while migrating the `storage-resize-images` extension to a Function Kit: firebase/extensions#3148 works around it by declaring the param as a string.
Contributor guide
Research direction
Start in src/deploy/functions/params.ts around promptSelect at lines 914-928, then inspect promptSelectMultiple around line 953 for the related list-default behavior. Reproduce the boolean select with MAKE_PUBLIC unset and verify that the declared default is matched after option values are converted; confirm the corresponding list behavior is also handled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100