Problem
The attachment download caching in downloadAttachmentToPath has two issues that combine to produce false cache hits:
1. Cache accepts directories as valid cached files
os.Stat(outPath) succeeds on directories, and since expectedSize == -1 the check is just st.Size() > 0. A directory always has Size() > 0 (typically 64-512 bytes depending on filesystem), so it passes the cache check and returns cached: true.
2. Cache doesn't validate content — any non-empty file is a "hit"
When expectedSize == -1 (which is always the case for GmailAttachmentCmd.Run), the cache check is:
if st, err := os.Stat(outPath); err == nil && st.Size() > 0 {
return outPath, true, st.Size(), nil
}
This means if any file exists at the output path (from a previous failed download, a different attachment, or even an unrelated file), it's returned as a cached result without any content validation.
Reproduction
# Write a small unrelated file to the output path
echo "not a PDF" > /tmp/invoice.pdf
# Try to download an attachment to the same path
gog gmail attachment <messageId> <attachmentId> --out /tmp/invoice.pdf
# Output: path=/tmp/invoice.pdf cached=true bytes=11
# Expected: should re-download the actual attachment (648KB PDF)
Suggested fix
In downloadAttachmentToPath:
- Check
st.Mode().IsRegular() to reject directories
- When
expectedSize > 0 is available, pass it through from the Gmail API metadata (the sizeEstimate field on the attachment) so the size check can reject wrong-sized files
- Consider adding a
--no-cache / --force-download flag for programmatic usage where cache correctness matters
At minimum, checking for regular files would prevent the most confusing case (directories being treated as cached attachments).
Filed by an AI agent on behalf of @schickling
Problem
The attachment download caching in
downloadAttachmentToPathhas two issues that combine to produce false cache hits:1. Cache accepts directories as valid cached files
os.Stat(outPath)succeeds on directories, and sinceexpectedSize == -1the check is justst.Size() > 0. A directory always hasSize() > 0(typically 64-512 bytes depending on filesystem), so it passes the cache check and returnscached: true.2. Cache doesn't validate content — any non-empty file is a "hit"
When
expectedSize == -1(which is always the case forGmailAttachmentCmd.Run), the cache check is:This means if any file exists at the output path (from a previous failed download, a different attachment, or even an unrelated file), it's returned as a cached result without any content validation.
Reproduction
Suggested fix
In
downloadAttachmentToPath:st.Mode().IsRegular()to reject directoriesexpectedSize > 0is available, pass it through from the Gmail API metadata (thesizeEstimatefield on the attachment) so the size check can reject wrong-sized files--no-cache/--force-downloadflag for programmatic usage where cache correctness mattersAt minimum, checking for regular files would prevent the most confusing case (directories being treated as cached attachments).
Filed by an AI agent on behalf of @schickling