Skip to content

fix: warn on malformed .env lines instead of silently skipping them#276

Open
spartan124 wants to merge 1 commit into
Grainlify:mainfrom
spartan124:fix/dotenv-malformed-line-warning-v2
Open

fix: warn on malformed .env lines instead of silently skipping them#276
spartan124 wants to merge 1 commit into
Grainlify:mainfrom
spartan124:fix/dotenv-malformed-line-warning-v2

Conversation

@spartan124

Copy link
Copy Markdown
Contributor

Closes #172

📌 Description

Previously, internal/config/dotenv.go utilized godotenv.Load() and silently ignored any
parsing errors. If a .env file contained a malformed line (e.g., missing =,
unterminated quote), a typo would silently cause variables to remain unset rather than
failing fast, surfacing later as confusing downstream errors.

This PR implements a robust warn-and-skip parser strategy. Instead of entirely aborting
.env loading, malformed lines are now isolated, loudly logged to stderr with a
descriptive warning, and skipped, allowing the remainder of the valid .env
configuration to be safely loaded.

🧩 Changes made

• Warn-and-Skip Parser Strategy: Replaced the bulk godotenv.Load() call with a custom
bufio.Scanner line-by-line wrapper.
• Enhanced Warning Logs: Malformed lines (missing = or unterminated quotes) now
correctly trigger a detailed WARNING log indicating the exact line context and file
path.
• Robust Duplicate Key Handling: Enforces explicit last-wins behavior within the same .
env file prior to updating the OS environment (which still safely ignores already-
exported OS variables).
• Added Full Test Suite: Created internal/config/dotenv_test.go covering edge cases to
guarantee stability.

🧪 Testing and Acceptance

go test ./internal/config/... -v -cover shows comprehensive test coverage over 95%.

The test suite explicitly verifies:

• ✅ Valid .env files parse identically to before.
• ✅ Missing = signs log a warning and correctly skip the single broken line.
• ✅ Unterminated quotes log a warning and properly capture block-level failures
without panicking.
• ✅ Duplicate keys resolve explicitly to a last-wins outcome within the file.
• ✅ Empty files and comment-only lines load gracefully.
• ✅ Existing OS environment variables are not overwritten.

Test Output

=== RUN   TestLoadDotenv                                                             
=== RUN   TestLoadDotenv/Valid_file
=== RUN   TestLoadDotenv/Missing_equals_sign
=== RUN   TestLoadDotenv/Unterminated_quote 
=== RUN   TestLoadDotenv/Duplicate_key_(last-wins)
=== RUN   TestLoadDotenv/Empty_file
=== RUN   TestLoadDotenv/Comment-only_line
=== RUN   TestLoadDotenv/Mixed_with_comments
=== RUN   TestLoadDotenv/Does_not_overwrite_existing_OS_env
--- PASS: TestLoadDotenv (0.21s)
PASS
ok      github.com/jagadeesh/grainlify/backend/internal/config    3.252s

🔒 Security Notes

Verified that no sensitive defaults are implicitly used as fallbacks if parsing fails.
This change only adds verbosity to local dev tooling; downstream validation layers
continue to gate execution on missing required variables.

@spartan124
spartan124 marked this pull request as ready for review July 25, 2026 19:37
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.

Reject malformed lines instead of silently skipping in internal/config/dotenv.go

1 participant