{"record":{"id":"94815670aaf41a89","repo":"tonhowtf/omniget","slug":"um-carrossel-tem-de-2-a-20-arquivos","errorCode":null,"errorMessage":"um carrossel tem de 2 a 20 arquivos","messagePattern":"um carrossel tem de 2 a 20 arquivos","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/instagram/publish.rs","lineNumber":460,"sourceCode":"                        return Ok(result_of(&json));\n                    }\n                    Ok(json) => last = Some(anyhow!(\"configure: {}\", json)),\n                    Err(IgError::Other(e))\n                        if e.contains(\"Transcode\")\n                            || e.contains(\"not ready\")\n                            || e.contains(\"202\") =>\n                    {\n                        last = Some(anyhow!(e));\n                    }\n                    Err(e) => return Err(m(e)),\n                }\n                tokio::time::sleep(std::time::Duration::from_secs(4 + attempt * 3)).await;\n            }\n            Err(last.unwrap_or_else(|| anyhow!(\"o Instagram nao confirmou o video\")))\n        }\n        \"carousel\" => {\n            if req.files.len() < 2 || req.files.len() > 20 {\n                return Err(anyhow!(\"um carrossel tem de 2 a 20 arquivos\"));\n            }\n            let total = req.files.len() as u64 + 1;\n            let sidecar_id = upload_id();\n            let mut children: Vec<Value> = Vec::new();\n            for (i, f) in req.files.iter().enumerate() {\n                report(\"upload\", i as u64, total);\n                let path = Path::new(f);\n                let uid = format!(\"{}{}\", upload_id(), i);\n                let is_video = matches!(\n                    path.extension()\n                        .and_then(|e| e.to_str())\n                        .map(|e| e.to_lowercase())\n                        .as_deref(),\n                    Some(\"mp4\" | \"mov\" | \"m4v\" | \"webm\")\n                );\n                if is_video {\n                    let (w, h, dur) = probe_video(path).await?;\n                    let bytes = tokio::fs::read(path).await?;","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/instagram/publish.rs#L442-L478","documentation":"For kind == 'carousel', publish_web enforces Instagram's sidecar limits: between 2 and 20 files. Requests outside this range fail with 'um carrossel tem de 2 a 20 arquivos' (a carousel has 2 to 20 files).","triggerScenarios":"Calling publish_web with kind 'carousel' and req.files.len() == 0, 1, or > 20.","commonSituations":"User selects a single image but the UI sends kind 'carousel' instead of 'photo', or a bulk selection exceeds Instagram's 20-item limit.","solutions":["Send kind 'photo' when there is exactly one file","Truncate or split selections larger than 20 items before building the request","Validate carousel file count in the UI before invoking publish_web"],"exampleFix":"// before\npublish({ kind: 'carousel', files: [singleFile] })\n// after\nconst kind = files.length === 1 ? 'photo' : 'carousel';\nif (files.length > 20) throw new Error('um carrossel tem de 2 a 20 arquivos');","handlingStrategy":"validation","validationCode":"if (kind === 'carousel' && (files.length < 2 || files.length > 20)) {\n  throw new Error('um carrossel tem de 2 a 20 arquivos');\n}","typeGuard":"function validCarousel(files) { return Array.isArray(files) && files.length >= 2 && files.length <= 20; }","tryCatchPattern":"try { await publish(req) } catch (e) { if (String(e).includes('2 a 20 arquivos')) { fixKindOrTruncate(req); } else { throw e; } }","preventionTips":["Auto-switch kind to 'photo' for single files","Cap file pickers at 20 for carousel mode","Validate counts client-side before building PublishRequest"],"tags":["validation","instagram","carousel","input-validation"],"backgroundTag":"value-out-of-range","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}