{"record":{"id":"41977df5d54845d5","repo":"toeverything/AFFiNE","slug":"invalidinput","errorCode":"InvalidInput","errorMessage":"invalid mobile file token","messagePattern":"invalid mobile file token","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"packages/frontend/mobile-native/src/cache/mod.rs","lineNumber":287,"sourceCode":"    for entry in std::fs::read_dir(cache_dir)? {\n      let entry = entry?;\n      if entry.path().is_file() {\n        let _ = std::fs::remove_file(entry.path());\n      }\n    }\n    Ok(())\n  }\n}\n\npub(crate) fn is_mobile_binary_file_token(value: &str) -> bool {\n  value.starts_with(MOBILE_BLOB_FILE_PREFIX)\n}\n\nimpl MobileBlobCache {\n  pub(crate) fn read_binary_file(&self, universal_id: &str, value: &str) -> std::io::Result<Vec<u8>> {\n    let path = value\n      .strip_prefix(MOBILE_BLOB_FILE_PREFIX)\n      .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidInput, \"invalid mobile file token\"))?;\n\n    let path = path.strip_prefix(\"file://\").unwrap_or(path);\n    let canonical = std::fs::canonicalize(path)?;\n    let workspace_dir = {\n      self\n        .workspace_dirs\n        .read()\n        .expect(\"workspace cache lock poisoned\")\n        .get(universal_id)\n        .cloned()\n    }\n    .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, \"workspace cache directory not registered\"))?;\n    let workspace_dir = std::fs::canonicalize(workspace_dir)?;\n\n    if !is_valid_mobile_cache_path(&canonical, &workspace_dir) {\n      return Err(std::io::Error::new(\n        std::io::ErrorKind::PermissionDenied,\n        \"mobile file token points outside the workspace cache directory\",","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/frontend/mobile-native/src/cache/mod.rs#L269-L305","documentation":"read_binary_file guard: the value passed as a blob reference does not carry the MOBILE_BLOB_FILE_PREFIX, so it is not a mobile file token at all; an InvalidInput io::Error is returned instead of attempting a filesystem read.","triggerScenarios":"Raised in read_binary_file when the stored value does not start with the expected MOBILE_BLOB_FILE_PREFIX, so the token cannot be stripped to a path.","commonSituations":"A blob value that is not a mobile file token was passed to the file reader. Only values produced by the mobile blob cache should be read this way.","solutions":["Issue a fresh mobile file token from the cache layer.","Do not forge or modify file tokens."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}