Problem
Users can upload unsupported file types that pass initial validation but fail during processing. Recent analysis shows 3 additional failure modes beyond ODM issues:
- COG Generation Failure (10% of failures) - DSM files uploaded as RGB orthomosaics
- Ortho Conversion Failure (10% of failures) - Corrupt or invalid image files
- Treecover Edge Cases (10% of failures) - Images too small or with invalid data
These failures waste processing time and provide unclear error messages to users.
Current Failure Modes
1. DSM Files Uploaded as RGB Orthomosaics (Dataset 6198)
File: Sime Darby XME1 DSM.tif
Problem:
- User uploaded Digital Surface Model (DSM - elevation data)
- System expects RGB orthomosaic (3-band color image)
- Ortho processing succeeds (file is valid GeoTIFF)
- COG generation fails when trying to extract RGB bands
Error:
Command 'gdal_translate ... -b 1 -b 2 -b 3 ...' returned non-zero exit status 1
Root Cause: File only has 1 band (elevation), not 3 bands (RGB)
Detection: Check band count during upload
with rasterio.open(file) as src:
if src.count == 1:
raise ValueError("File has only 1 band. Upload RGB orthomosaics (3 bands), not DSM/DTM files.")
2. Corrupt or Invalid Image Files (Dataset 6182)
File: WhatsApp Image 2025-10-15 at 08.47.18.tif
Problem:
- File uploaded via WhatsApp (likely compressed/corrupted)
- Passes upload but fails during standardization
- Error message: "convert processing failed: Conversion failed"
Root Cause: File corruption or unsupported compression format
Detection: Validate file integrity during upload
from PIL import Image
try:
with Image.open(file) as img:
img.verify() # Check file integrity
img.load() # Attempt to read pixel data
except Exception as e:
raise ValueError(f"File appears to be corrupt or invalid: {str(e)}")
3. Treecover Segmentation Edge Cases (Datasets 3182, 6036)
Empty Batch Error (Dataset 3182)
Problem:
- Image too small: 1024×1024 px at 0.1m resolution
- TCD pipeline skips all batches
- Error: "Empty batch, skipping" → No output tiles
Root Cause: Image below minimum size for treecover detection
Detection: Check image dimensions before treecover processing
MIN_SIZE_FOR_TREECOVER = 2048 # pixels
if width < MIN_SIZE_FOR_TREECOVER or height < MIN_SIZE_FOR_TREECOVER:
raise ValueError(f"Image too small for treecover segmentation: {width}×{height}. Minimum: {MIN_SIZE_FOR_TREECOVER}×{MIN_SIZE_FOR_TREECOVER}")
Chunk and Warp Failed (Dataset 6036)
Problem:
- Large untiled GeoTIFF causes GDAL reprojection failure
- Error: "Chunk and warp failed"
Status: Should be fixed by local file caching mechanism (processor-pipeline rules)
Verification Needed: Check if fix is deployed in production
Proposed Solution
Upload-Time Validation
File: api/src/upload/geotiff_processor.py
Add comprehensive GeoTIFF validation during upload:
async def validate_geotiff_for_processing(file_path: Path) -> dict[str, str | None]:
"""
Validate uploaded GeoTIFF is suitable for processing pipeline.
Returns: {"error": None} if valid, {"error": "message"} if invalid
"""
try:
with rasterio.open(file_path) as src:
# Check band count (need RGB)
if src.count == 1:
return {
"error": "File has only 1 band (likely DSM/DTM). "
"Please upload RGB orthomosaics with 3 or 4 bands. "
"DSM files are not supported."
}
if src.count not in [3, 4]:
return {
"error": f"File has {src.count} bands. "
"Supported: 3 bands (RGB) or 4 bands (RGBA)."
}
# Check dimensions (minimum for processing)
if src.width < 512 or src.height < 512:
return {
"error": f"Image too small: {src.width}×{src.height} pixels. "
"Minimum: 512×512 pixels."
}
# Check for CRS (required for processing)
if src.crs is None:
return {
"error": "File lacks coordinate reference system (CRS). "
"Please upload georeferenced GeoTIFFs only."
}
# Try reading sample pixels (detect corruption)
try:
_ = src.read(1, window=Window(0, 0, 100, 100))
except Exception as e:
return {
"error": f"Failed to read pixel data. File may be corrupt: {str(e)}"
}
return {"error": None}
except Exception as e:
return {"error": f"Invalid GeoTIFF file: {str(e)}"}
# In process_geotiff_upload():
async def process_geotiff_upload(...):
# Validate file before creating dataset
validation = await validate_geotiff_for_processing(temp_file_path)
if validation["error"]:
raise ValueError(validation["error"])
# ... continue with upload
Processing-Time Checks
Files:
processor/src/process_cog.py (check bands before COG generation)
processor/src/process_treecover_segmentation.py (check dimensions before segmentation)
Add defensive checks before expensive operations:
# Before COG generation
if band_count == 1:
raise ValueError("Cannot create RGB COG from single-band file. Skipping COG generation.")
# Before treecover segmentation
if width < 2048 or height < 2048:
logger.warning(f"Image too small for treecover: {width}×{height}. Skipping segmentation.")
# Mark as completed without error (not a failure)
Impact
Current Failure Statistics (Past 30 Days)
Expected Benefits
- Fail fast: Reject invalid files at upload (not after 20 minutes processing)
- Clear errors: Explain what's wrong and how to fix it
- Save resources: Avoid wasted processing time on invalid files
- Better UX: Users understand requirements before uploading
Acceptance Criteria
Upload Validation
Processing Validation
Testing
Priority
Medium - Affects 20-30% of failures, but less frequent than ODM issues
Recommend implementing after #223 and #224 (which address 60% of failures).
Related Issues
This issue complements those by covering non-ODM failure modes.
Problem
Users can upload unsupported file types that pass initial validation but fail during processing. Recent analysis shows 3 additional failure modes beyond ODM issues:
These failures waste processing time and provide unclear error messages to users.
Current Failure Modes
1. DSM Files Uploaded as RGB Orthomosaics (Dataset 6198)
File:
Sime Darby XME1 DSM.tifProblem:
Error:
Root Cause: File only has 1 band (elevation), not 3 bands (RGB)
Detection: Check band count during upload
2. Corrupt or Invalid Image Files (Dataset 6182)
File:
WhatsApp Image 2025-10-15 at 08.47.18.tifProblem:
Root Cause: File corruption or unsupported compression format
Detection: Validate file integrity during upload
3. Treecover Segmentation Edge Cases (Datasets 3182, 6036)
Empty Batch Error (Dataset 3182)
Problem:
Root Cause: Image below minimum size for treecover detection
Detection: Check image dimensions before treecover processing
Chunk and Warp Failed (Dataset 6036)
Problem:
Status: Should be fixed by local file caching mechanism (processor-pipeline rules)
Verification Needed: Check if fix is deployed in production
Proposed Solution
Upload-Time Validation
File:
api/src/upload/geotiff_processor.pyAdd comprehensive GeoTIFF validation during upload:
Processing-Time Checks
Files:
processor/src/process_cog.py(check bands before COG generation)processor/src/process_treecover_segmentation.py(check dimensions before segmentation)Add defensive checks before expensive operations:
Impact
Current Failure Statistics (Past 30 Days)
Expected Benefits
Acceptance Criteria
Upload Validation
Processing Validation
Testing
Priority
Medium - Affects 20-30% of failures, but less frequent than ODM issues
Recommend implementing after #223 and #224 (which address 60% of failures).
Related Issues
This issue complements those by covering non-ODM failure modes.