Anatomi Pesan Error
Ketika kamu bekerja dengan Salesforce DX di Visual Studio Code, ada kalanya kamu menemui pesan error yang menghentikan seluruh alur kerja deployment-mu. Pesan error tersebut muncul secara verbatim sebagai berikut:
this org does not have source trackingPesan ini biasanya muncul saat kamu menjalankan perintah sfdx force:source:push atau sfdx force:source:pull, terutama ketika bekerja dengan scratch org atau sandbox melalui Salesforce CLI yang terintegrasi dengan ekstensi Salesforce Extension Pack di VSCode. Error ini tidak memberikan stack trace panjang atau kode error numerik — hanya kalimat pendek itu — sehingga sering kali membingungkan developer yang baru pertama kali menghadapinya.
Dalam bahasa Indonesia, pesan ini berarti: "Organisasi ini tidak memiliki pelacakan sumber (source tracking)." Artinya, Salesforce CLI mencoba melakukan operasi yang bergantung pada fitur source tracking — yaitu kemampuan sistem untuk membandingkan keadaan metadata di lokal dengan keadaan metadata di org secara incremental — tetapi org yang sedang aktif (default username) tidak mendukung atau tidak mengaktifkan fitur tersebut.
Kenapa error ini muncul? Secara teknis, source tracking adalah mekanisme di balik force:source:push dan force:source:pull yang memungkinkan CLI mengetahui apa saja yang berubah sejak push/pull terakhir. Mekanisme ini hanya tersedia pada scratch org dan sandbox yang dikonfigurasi sebagai source-tracked org. Jika kamu menargetkan org yang bukan scratch org — misalnya Developer Edition, Production org, atau sandbox tanpa source tracking — maka CLI akan menolak operasi dan melempar pesan error ini. terus, error ini juga bisa muncul jika scratch org sudah expired, jika konfigurasi sfdx-project.json tidak sesuai, atau jika kamu menggunakan versi Salesforce CLI yang sudah outdated sehingga perilaku source tracking-nya berbeda dari yang diharapkan.
Berikut contoh situasi nyata ketika error ini muncul:
$ sfdx force:source:push -u my-org-alias
ERROR: this org does not have source tracking.Atau saat menjalankan pull:
$ sfdx force:source:pull -u my-sandbox
ERROR: this org does not have source tracking.Perhatikan bahwa error ini bersifat hard stop — bukan warning. CLI tidak akan melanjutkan operasi sama sekali, sehingga kamu harus memperbaiki kondisi yang menyebabkannya sebelum bisa kembali bekerja.
Penyebab Umum
Memahami akar masalah adalah langkah paling penting sebelum mencoba memperbaikinya. Berikut lima penyebab paling umum yang memicu error "this org does not have source tracking", diurutkan dari yang paling sering terjadi di lapangan.
1. Menargetkan org non-scratch (Developer Edition, Production, atau sandbox non-source-tracked). Ini adalah penyebab paling dominan. Banyak developer secara tidak sengaja menjalankan force:source:push atau force:source:pull terhadap org yang bukan scratch org. Perintah-perintah ini memang dirancang khusus untuk scratch org. Jika default username di CLI mengarah ke org jenis lain, error ini akan langsung muncul. Cara memastikan: jalankan sfdx force:org:list dan perhatikan kolom yang menunjukkan jenis org. Scratch org akan muncul di bagian terpisah dari org non-scratch.
$ sfdx force:org:list
=== Orgs
ALIAS USERNAME ORG ID CONNECTED STATUS
─────────── ───────────────────────────── ────────────────── ─────────────────
myDevHub devhub@example.com 00D5f000004xxxx Connected
=== Scratch Orgs
ALIAS USERNAME ORG ID EXPIRATION DATE
─────────── ───────────────────────────── ────────────────── ────────────────
my-scratch test-abc@scratch.example.com 00D5f000005xxxx 2024-12-302. Scratch org sudah expired atau rusak (corrupted state). Scratch org memiliki masa hidup terbatas, biasanya 7 hari jika tidak dikonfigurasi. Setelah expired, org masih bisa muncul di daftar tetapi sudah tidak bisa diakses dengan normal, dan source tracking-nya tidak lagi valid. Cara memastikan: cek expiration date dari output sfdx force:org:list, atau coba jalankan sfdx force:org:open -u <alias> — jika org expired, browser akan menampilkan halaman login Salesforce alih-alih langsung masuk.
3. Versi Salesforce CLI yang sudah outdated. Salesforce CLI berkembang cepat, dan perilaku source tracking telah mengalami beberapa perubahan besar, terutama saat transisi dari sfdx ke sf CLI (v2+). Versi lama mungkin tidak mendukung source tracking untuk jenis org tertentu atau memiliki bug yang sudah diperbaiki di versi lebih baru. Cara memastikan: jalankan sfdx --version atau sf --version dan bandingkan dengan versi terbaru yang tersedia di npm.
$ sfdx --version
sfdx-cli/7.209.2
$ sf --version
@salesforce/cli/2.56.84. File .sfdx/sfdx-config.json atau konfigurasi defaultusername rusak. Default username yang disimpan oleh CLI bisa mengarah ke org yang salah jika sebelumnya kamu pernah authorize beberapa org dan ada perubahan state yang tidak tercatat dengan benar. Cara memastikan: jalankan sfdx force:config:get defaultusername dan verifikasi bahwa nilai yang dikembalikan sesuai dengan scratch org yang kamu inginkan.
$ sfdx force:config:get defaultusername
defaultusername my-old-non-scratch-org@example.com Local5. Sandbox yang belum diaktifkan source tracking-nya. Sejak Salesforce CLI v2, ada dukungan source tracking untuk sandbox tertentu, tetapi fitur ini harus diaktifkan secara eksplisit atau membutuhkan konfigurasi tambahan. Jika kamu menggunakan sandbox sebagai target dan mengharapkan perilaku seperti scratch org, kamu bisa mendapatkan error ini. Cara memastikan: cek apakah org-mu adalah sandbox dengan sfdx force:org:display -u <alias> dan lihat atribut yang ditampilkan.
Cara Memperbaiki
Bagian ini menjelaskan langkah-langkah perbaikan secara sekuensial — mulai dari diagnosis hingga verifikasi. Setiap langkah dilengkapi perintah yang bisa kamu jalankan langsung di terminal dan output yang diharapkan.
Langkah 1: Identifikasi org yang sedang aktif
Jalankan perintah berikut untuk melihat org mana yang sedang menjadi default target:
$ sfdx force:config:get defaultusernameOutput yang diharapkan:
defaultusername my-scratch-alias LocalJika nilai yang muncul adalah alias atau username dari org non-scratch (misalnya production atau developer edition), maka inilah penyebab error-mu. Lanjutkan ke Langkah 2.
Langkah 2: Verifikasi bahwa target org adalah scratch org yang masih aktif
Jalankan perintah berikut:
$ sfdx force:org:list --cleanPerintah --clean akan menghapus referensi ke org yang sudah expired dari daftar lokal. Output-nya akan memisahkan antara org biasa dan scratch org. Pastikan alias yang kamu tuju muncul di bagian Scratch Orgs dan expiration date-nya belum lewat.
Jika scratch org-mu sudah expired, kamu perlu membuat scratch org baru:
$ sfdx force:org:create -f config/project-scratch-def.json -a my-new-scratch -dFlag -d membuat org ini sebagai default scratch org, dan -a memberikan alias. Output yang diharapkan:
Successfully created scratch org: 00D5f000006xxxx, username: test-xyz@scratch.example.comLangkah 3: Set default username ke scratch org yang benar
Jika scratch org-mu masih aktif tetapi bukan default, set secara eksplisit:
$ sfdx force:config:set defaultusername=my-scratch-aliasOutput yang diharapkan:
Set config defaultusername to my-scratch-alias.Sekarang, semua perintah force:source:push dan force:source:pull akan menargetkan scratch org ini secara default.
Langkah 4: Coba jalankan kembali perintah yang sebelumnya error
$ sfdx force:source:pushJika semua langkah di atas benar, output yang diharapkan adalah daftar metadata yang di-push (atau pesan "No changes found to push" jika lokal dan org sudah sinkron):
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ───────────────── ────────── ───────────────────────────────
Add AccountTrigger ApexTrigger force-app/main/default/triggers/AccountTrigger.trigger
Add MyCustomObject CustomObject force-app/main/default/objects/MyCustomObject/MyCustomObject.object-meta.xmlLangkah 5: Verifikasi solusi berhasil
Untuk memverifikasi bahwa source tracking benar-benar berfungsi, kamu bisa membuat perubahan kecil di lokal, push, lalu pull. Jika pull mengembalikan "No changes found to pull" (karena lokal dan org sudah sinkron), maka source tracking bekerja dengan benar.
$ sfdx force:source:pullOutput yang diharapkan:
No changes found to pull.Solusi langsung berdasarkan root cause
Jika penyebabnya adalah org bukan scratch org, solusi permanennya adalah selalu gunakan scratch org untuk development dan gunakan force:source:deploy (bukan push) untuk org non-scratch:
# Untuk scratch org (source tracking aktif):
$ sfdx force:source:push -u my-scratch
# Untuk org non-scratch (tanpa source tracking):
$ sfdx force:source:deploy -p force-app/main/default -u my-prod-orgJika penyebabnya adalah CLI outdated, update terlebih dahulu:
$ npm update -g sfdx-cli
# Atau untuk CLI v2:
$ npm update -g @salesforce/cliFix Permanen (Bukan Workaround)
Memperbaiki error ketika muncul itu penting, tetapi mencegahnya muncul kembali jauh lebih bernilai. Bagian ini membahas konfigurasi dan best practice yang secara fundamental mencegah error "this org does not have source tracking" kembali menghantui workflow-mu.
Konfigurasi sfdx-project.json yang benar
File sfdx-project.json adalah fondasi dari setiap proyek Salesforce DX. Pastikan konfigurasi-nya mengacu pada scratch org definition file yang valid dan package directory yang benar:
{
"packageDirectories": [
{
"path": "force-app",
"default": true
}
],
"namespace": "",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "59.0"
}Poin kritis: sourceApiVersion harus sesuai dengan API version yang didukung oleh scratch org-mu. Jika kamu menggunakan API version yang terlalu lama, beberapa fitur source tracking mungkin tidak berfungsi dengan baik di kombinasi CLI tertentu.
Script alias untuk mencegah salah target
Banyak developer terkena error ini karena lupa menentukan flag -u dan mengandalkan default username yang bisa berubah tanpa sengaja. Solusi permanen: buat npm script atau shell alias yang selalu eksplisit menentukan target org.
Dalam package.json:
{
"scripts": {
"push:scratch": "sfdx force:source:push -u my-scratch",
"pull:scratch": "sfdx force:source:pull -u my-scratch",
"deploy:sandbox": "sfdx force:source:deploy -p force-app/main/default -u my-sandbox",
"org:check": "sfdx force:org:display -u my-scratch"
}
}Dengan cara ini, kamu tidak pernah lagi menjalankan push tanpa target yang jelas. Cukup npm run push:scratch dan kamu yakin bahwa target-nya selalu benar.
Git hooks untuk validasi sebelum push
Kamu juga bisa menambahkan pre-push hook yang memvalidasi apakah default username adalah scratch org. Berikut contoh skrip bash untuk Husky (git hooks manager):
#!/usr/bin/env bash
# .husky/pre-push
DEFAULT_USERNAME=$(sfdx force:config:get defaultusername --json | jq -r '.result[0].value')
# Cek apakah default username mengandung kata "scratch" (konvensi naming)
if [[ ! "$DEFAULT_USERNAME" =~ scratch ]]; then
echo "⚠️ WARNING: Default username '$DEFAULT_USERNAME' doesn't appear to be a scratch org."
echo " Aborting push to prevent 'this org does not have source tracking' error."
exit 1
fiPerbedaan antar OS
Konfigurasi CLI disimpan di lokasi yang berbeda tergantung sistem operasi, dan ini bisa menjadi sumber masalah jika kamu bekerja di multi-platform:
- Windows:
%LOCALAPPDATA%\sfdx\atau%USERPROFILE%\.sfdx\ - macOS/Linux:
~/.sfdx/
File kunci yang perlu diperhatikan adalah ~/.sfdx/sfdx-config.json (atau equivalent Windows). Jika file ini korup — misalnya berisi JSON yang tidak valid atau duplikat key — CLI bisa mengarah ke org yang salah. Periksa secara manual:
# macOS/Linux
$ cat ~/.sfdx/sfdx-config.json
# Windows (PowerShell)
> Get-Content "$env:LOCALAPPDATA\sfdx\sfdx-config.json"Pastikan file ini berisi sesuatu seperti:
{
"defaultusername": "my-scratch-alias",
"defaultdevhubusername": "my-devhub-alias"
}Jika isinya salah, edit langsung atau jalankan sfdx force:config:set untuk memperbaiki.
Best practice jangka panjang
Pertama, selalu buat scratch org fresh untuk setiap story atau task baru. Scratch org memang dirancang ephemeral — gunakan, lalu buang. Jangan mencoba "merawat" satu scratch org selama berminggu-minggu karena risiko expired dan corrupted state meningkat. Kedua, selalu gunakan force:source:deploy untuk org non-scratch dan simpan force:source:push/pull hanya untuk scratch org. Ketiga, dokumentasikan alias konvensi di tim — misalnya semua scratch org harus memiliki alias yang diawali scratch- — sehingga mudah dibedakan dari org lain dalam output CLI.
Kalau Masih Belum Teratasi
Terkadang, meskipun kamu sudah mengikuti semua langkah di atas, error ini tetap muncul. Situasi seperti ini frustrating, tetapi ada jalur diagnosis lebih dalam yang bisa kamu tempuh.
Ketika solusi standar tidak work
Jika kamu sudah memastikan bahwa target org adalah scratch org yang masih aktif, CLI sudah versi terbaru, default username sudah benar, tetapi error tetap muncul, kemungkinan besar ada state corruption di cache source tracking lokal. Salesforce CLI menyimpan state source tracking di direktori tersembunyi:
# macOS/Linux
$ ls ~/.sfdx/source-tracking/
# Windows (PowerShell)
> Get-ChildItem "$env:LOCALAPPDATA\sfdx\source-tracking\"Di dalam direktori ini, ada file JSON per org yang melacak perubahan terakhir. Jika file ini korup — misalnya karena proses push diinterupsi, disk penuh, atau konflik merge — CLI bisa salah menganggap bahwa org tidak memiliki source tracking. Solusi yang cukup drastis tetapi efektif adalah menghapus cache source tracking:
# macOS/Linux
$ rm -rf ~/.sfdx/source-tracking/
# Windows (PowerShell)
> Remove-Item -Recurse -Force "$env:LOCALAPPDATA\sfdx\source-tracking\"Setelah dihapus, CLI akan membuat ulang state source tracking dari awal saat push/pull berikutnya. Perhatikan bahwa ini berarti push/pull pertama setelah penghapusan bisa memakan waktu lebih lama karena CLI harus melakukan full comparison.
Alternatif yang lebih halus: alih-alih menghapus seluruh direktori, hapus hanya file yang terkait org spesifik. Cari file yang nama-nya mengandung org ID-mu:
$ sfdx force:org:display -u my-scratch --json | jq -r '.result.id'Output berupa org ID seperti 00D5f000006xxxx. Lalu hapus file yang mengandung ID tersebut dari source-tracking/.
Cara membaca log untuk diagnosis lebih dalam
Salesforce CLI memiliki flag --loglevel yang bisa menghasilkan output verbose sangat detail:
$ sfdx force:source:push -u my-scratch --loglevel traceLevel log dari paling sedikit ke paling banyak: error, warn, info, debug, trace. Untuk masalah source tracking, debug atau trace adalah yang paling berguna. Output-nya akan sangat panjang, jadi sebaiknya pipa ke file:
$ sfdx force:source:push -u my-scratch --loglevel debug 2>&1 | tee push-debug.logDalam log, cari baris yang mengandung kata "sourceTracking", "SourceTracking", atau "source tracking". Kamu akan menemukan informasi seperti apakah CLI berhasil membaca file state, apakah org dianggap sebagai scratch org oleh CLI, dan di titik mana proses gagal. Contoh informasi berharga dari log:
DEBUG: SourceTracking: checking org 00D5f000006xxxx for source tracking support
DEBUG: SourceTracking: org is a scratch org = true
DEBUG: SourceTracking: source tracking file exists = false
DEBUG: SourceTracking: creating new source tracking stateJika baris "org is a scratch org" menunjukkan false, meskipun org-mu seharusnya scratch org, ada masalah di metadata org tersebut — kemungkinan org sudah expired atau ter-disconnect dari Dev Hub.
Sumber resmi untuk deep-dive
Jika kamu sudah sampai pada titik ini dan masalah belum terpecahkan, berikut sumber resmi yang bisa kamu gali lebih dalam:
- Salesforce CLI Documentation: developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta — Referensi lengkap semua perintah CLI beserta flag dan perilakunya.
- Salesforce DX Developer Guide: Bagian tentang "Source Tracking" menjelaskan arsitektur di balik mekanisme ini dan kapan ia didukung atau tidak.
- GitHub Issue Tracker Salesforce CLI: github.com/forcedotcom/cli/issues — Cari issue dengan kata kunci "source tracking" — banyak developer lain mungkin sudah melaporkan kasus yang sama dengan solusi spesifik.
- Salesforce Stack Exchange: salesforce.stackexchange.com — Komunitas Q&A yang sangat aktif; tag
sfdx-clidansource-trackingrelevan. - Salesforce Developer Forums: developer.salesforce.com/forums — Alternatif lain untuk mendapatkan jawaban dari komunitas atau Salesforce staff.
Sebagai catatan penutup, error "this org does not have source tracking" memang terasa menghalangi, tetapi hampir selalu penyebabnya bisa dilacak ke salah satu dari lima root cause yang sudah kita bahas. Dengan memahami anatomi error-nya, mengikuti langkah perbaikan secara sistematis, dan menerapkan fix permanen berupa konfigurasi dan best practice yang tepat, kamu bisa mengeliminasi error ini dari workflow sehari-hari secara total — bukan hanya menambalnya ketika muncul. Investasi waktu untuk menyiapkan alias, script, dan validasi hook akan terbayar berkali-kali dalam bentuk workflow yang tenang dan produktif.