createLogger: invalid logger string (e.g. typo'd 'VERBOSE') silently passes through and crashes with 'logger.state is not a function'
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- typescript
- Domain
- cli
Research direction
Start in src/loggers.ts at createLogger and review the existing tests in src/test/loggers.test.ts. Run those logger tests first, then cover unknown and empty string values using the issue's preferred validation behavior. Done means invalid logger strings produce a clear error while the existing verbose, omitted, and Logger-object cases remain valid.
Written by the indexing model from the issue text.
Description
Severity
S3. Reasonable users hit this by writing \"logger\": \"VERBOSE\" (or any string other than the exact lowercase verbose) in their JSON config. The failure is loud but the error is opaque and doesn't mention the offending field, so debugging starts in the wrong place.
Observed behavior
createLogger in src/loggers.ts performs a single equality check against the string 'verbose', then falls back to a nullish-coalescing default:
export function createLogger(loggerSpec: LoggerSpec): Logger {
if (loggerSpec === 'verbose') {
return new VerboseLogger(true);
}
return loggerSpec ?? new VerboseLogger(false);
}
Any value that is neither the literal 'verbose' nor nullish is returned unchanged and the loop then treats it as a Logger. Because TypeScript believes the return type is Logger, the first method call on the result crashes with a TypeError.
Reproduced via the CLI with a minimal config:
{
\"name\": \"test\",
\"agent\": [\"test\", { \"responses\": [{ \"status\": \"success\", \"output\": \"ok\" }] }],
\"promptGenerator\": [\"test\", { \"prompts\": [\"hello\"] }],
\"logger\": \"VERBOSE\",
\"maxPrompts\": 1,
\"interPromptPause\": 0
}
$ node dist/cli.js bad-config.json
logger.state is not a function
The same happens for any other invalid value that survives the ?? operator: \"Verbose\", \"verbose \", \"quiet\", \"\" (empty string), true, 0, etc. Programmatic callers can only hit this via as any casts, but JSON config users hit it directly because loadCliConfig parses with JSON.parse(raw) as LoopCliConfig and does no runtime validation.
The JSON schema at schema/loop-the-loop.schema.json declares \"logger\": { \"enum\": [\"verbose\"] }, but loadCliConfig does not run schema validation, and none of the bundled examples set logger in their config (users typically reach for --verbose), so the schema does not protect the runtime path.
Expected behavior
createLogger should either:
- Throw a clear error when handed an unrecognised string (e.g.
Invalid logger value 'VERBOSE': expected 'verbose' or omit the field), or - Silently treat unknown values as 'quiet' (return a disabled
VerboseLogger).
Option 1 is more in keeping with the project's other input-validation helpers (parseArgs, assertTestTaskConfig, etc.) and matches the spirit of issues like #23, #24 and #33 where silent coercion was rejected.
Minimal reproduction
import { createLogger } from 'loop-the-loop/loggers';
const log = createLogger('VERBOSE' as any);
log.state('hi'); // TypeError: log.state is not a function
Or via the CLI as shown above with a config whose \"logger\" field is anything other than the exact string \"verbose\".
Suggested fix
export function createLogger(loggerSpec: LoggerSpec): Logger {
if (loggerSpec === undefined) {
return new VerboseLogger(false);
}
if (loggerSpec === 'verbose') {
return new VerboseLogger(true);
}
if (typeof loggerSpec === 'string') {
throw new Error(
\`Invalid logger value '\${loggerSpec}': expected 'verbose' or omit the field.\`,
);
}
return loggerSpec;
}
Add tests for the new branch (unknown string throws, empty string throws) alongside the existing createLogger tests in src/test/loggers.test.ts.
- Dominant language
- TypeScript
- Stars
- 2
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from joewalker/loop-the-loop
-
bug S4
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
joewalker/loop-the-loop#88 ·
-
Git exec(): child killed by a signal rejects with new Error('') and loses the signal information Openbug S3
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
joewalker/loop-the-loop#84 ·
-
bug S3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
joewalker/loop-the-loop#83 ·
-
bug S3
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
joewalker/loop-the-loop#82 ·
-
bug S4
Difficulty 1/5 Under an hour Newbie friendliness 90/100
joewalker/loop-the-loop#79 ·
All issues in joewalker/loop-the-loop
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100