{"record":{"id":"4942d80d719315c5","repo":"microg/GmsCore","slug":"cannot-set-null-temp-directory","errorCode":null,"errorMessage":"Cannot set null temp directory","messagePattern":"Cannot set null temp directory","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"play-services-base/src/main/java/com/google/android/gms/common/data/BitmapTeleporter.java","lineNumber":90,"sourceCode":"                    ByteBuffer wrap = ByteBuffer.wrap(bArr);\n                    Bitmap createBitmap = Bitmap.createBitmap(readInt, readInt2, valueOf);\n                    createBitmap.copyPixelsFromBuffer(wrap);\n                    this.targetBitmap = createBitmap;\n                    this.isParceled = true;\n                } catch (IOException e) {\n                    throw new IllegalStateException(\"Could not read from parcel file descriptor\", e);\n                }\n            } catch (Throwable th) {\n                close(dataInputStream);\n                throw th;\n            }\n        }\n        return this.targetBitmap;\n    }\n\n    public final void setTargetDirectory(File file) {\n        if (file == null) {\n            throw new NullPointerException(\"Cannot set null temp directory\");\n        }\n        this.targetDirectory = file;\n    }\n\n    private static void close(Closeable closeable) {\n        try {\n            closeable.close();\n        } catch (IOException e) {\n            Log.w(\"BitmapTeleporter\", \"Could not close stream\", e);\n        }\n    }\n\n    @Override\n    public void writeToParcel(@NonNull Parcel dest, int flags) {\n        CREATOR.writeToParcel(this, dest, flags);\n    }\n\n    public static final SafeParcelableCreatorAndWriter<BitmapTeleporter> CREATOR = findCreator(BitmapTeleporter.class);","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-base/src/main/java/com/google/android/gms/common/data/BitmapTeleporter.java#L72-L108","documentation":"BitmapTeleporter.setTargetDirectory throws this NullPointerException when passed a null File. The directory is required because the teleporter writes the bitmap to a temp file in it during parceling; a null target would make the write path fail later, so it is rejected eagerly.","triggerScenarios":"Calling teleporter.setTargetDirectory(null) directly; passing a field or lookup result that is null, e.g. context.getExternalFilesDir(null) on storage-unavailable devices, or Environment.getExternalStorageDirectory() results that callers blindly forward.","commonSituations":"Devices with external storage unmounted where getExternalFilesDir returns null; initialization code running before storage is ready; refactors that replace a default directory with a nullable provider.","solutions":["Pass a guaranteed-writable directory: new File(context.getCacheDir(), \"bmp_temp\") is always non-null.","If using external storage, null-check getExternalFilesDir(...) and fall back to cacheDir before calling setTargetDirectory.","Validate the argument before the call in your own helper so the failure carries your message.","Call setTargetDirectory early (before parceling) so misconfiguration surfaces during setup, not during transfer."],"exampleFix":"// before\nteleporter.setTargetDirectory(context.getExternalFilesDir(null)); // may be null\n\n// after\nFile dir = context.getExternalFilesDir(null);\nteleporter.setTargetDirectory(dir != null ? dir : new File(context.getCacheDir(), \"bmp_temp\"));","handlingStrategy":"validation","validationCode":"File dir = context.getExternalFilesDir(null);\nif (dir == null) dir = new File(context.getCacheDir(), \"bmp_temp\");\nif (!dir.exists()) dir.mkdirs();\nteleporter.setTargetDirectory(dir);","typeGuard":"boolean isValidTargetDirectory(File f) {\n    return f != null && f.exists() ? f.isDirectory() : f != null;\n}","tryCatchPattern":"try {\n    teleporter.setTargetDirectory(dir);\n} catch (NullPointerException e) {\n    teleporter.setTargetDirectory(new File(context.getCacheDir(), \"bmp_temp\"));\n}","preventionTips":["Null-check getExternalFilesDir() results before use; it returns null when storage is unavailable.","Default to internal cacheDir for temp bitmap storage.","Call setTargetDirectory during setup, before any parceling.","Wrap nullable directory providers in a small resolver helper."],"tags":["android","null-pointer","temp-directory","bitmap"],"backgroundTag":"null-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}